summaryrefslogtreecommitdiff
path: root/src/third_party/boost-1.60.0/boost/thread
diff options
context:
space:
mode:
authorMark Benvenuto <mark.benvenuto@mongodb.com>2016-03-31 15:09:29 -0400
committerMark Benvenuto <mark.benvenuto@mongodb.com>2016-03-31 15:09:29 -0400
commit869912de45bfec53f8fd15c4f716b49ac2ca7aa4 (patch)
tree97934f62054ebb1f1c78812196f7c7bded1fc1b3 /src/third_party/boost-1.60.0/boost/thread
parent319e895cc28b4aade6fa843583e0fd2ea96cd7a0 (diff)
downloadmongo-869912de45bfec53f8fd15c4f716b49ac2ca7aa4.tar.gz
SERVER-17294 Boost 1.60
Diffstat (limited to 'src/third_party/boost-1.60.0/boost/thread')
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/barrier.hpp254
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/caller_context.hpp59
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/completion_latch.hpp226
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/concurrent_queues/deque_adaptor.hpp209
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/concurrent_queues/deque_base.hpp202
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/concurrent_queues/deque_views.hpp165
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/concurrent_queues/detail/sync_deque_base.hpp223
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/concurrent_queues/detail/sync_queue_base.hpp223
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/concurrent_queues/queue_adaptor.hpp209
-rwxr-xr-xsrc/third_party/boost-1.60.0/boost/thread/concurrent_queues/queue_base.hpp202
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/concurrent_queues/queue_op_status.hpp46
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/concurrent_queues/queue_views.hpp155
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/concurrent_queues/sync_bounded_queue.hpp725
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/concurrent_queues/sync_deque.hpp327
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/concurrent_queues/sync_priority_queue.hpp369
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/concurrent_queues/sync_queue.hpp335
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/concurrent_queues/sync_timed_queue.hpp466
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/condition.hpp21
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/condition_variable.hpp21
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/csbl/deque.hpp45
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/csbl/devector.hpp102
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/csbl/functional.hpp49
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/csbl/list.hpp35
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/csbl/memory.hpp61
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/csbl/memory/allocator_arg.hpp41
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/csbl/memory/allocator_traits.hpp35
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/csbl/memory/config.hpp16
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/csbl/memory/default_delete.hpp41
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/csbl/memory/pointer_traits.hpp35
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/csbl/memory/scoped_allocator.hpp35
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/csbl/memory/shared_ptr.hpp42
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/csbl/memory/unique_ptr.hpp28
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/csbl/queue.hpp45
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/csbl/tuple.hpp49
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/csbl/vector.hpp35
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/cv_status.hpp26
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/detail/config.hpp465
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/detail/counter.hpp106
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/detail/delete.hpp58
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/detail/force_cast.hpp39
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/detail/function_wrapper.hpp93
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/detail/invoke.hpp1604
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/detail/invoker.hpp762
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/detail/is_convertible.hpp49
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/detail/lockable_wrapper.hpp45
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/detail/log.hpp83
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/detail/make_tuple_indices.hpp224
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/detail/memory.hpp48
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/detail/move.hpp374
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/detail/nullary_function.hpp234
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/detail/platform.hpp73
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/detail/singleton.hpp59
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/detail/thread.hpp873
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/detail/thread_group.hpp155
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/detail/thread_heap_alloc.hpp23
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/detail/thread_interruption.hpp39
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/detail/tss_hooks.hpp65
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/detail/variadic_footer.hpp10
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/detail/variadic_header.hpp19
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/exceptional_ptr.hpp44
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/exceptions.hpp225
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/executor.hpp15
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/executors/basic_thread_pool.hpp318
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/executors/detail/priority_executor_base.hpp77
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/executors/detail/scheduled_executor_base.hpp66
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/executors/executor.hpp148
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/executors/executor_adaptor.hpp136
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/executors/generic_executor_ref.hpp213
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/executors/inline_executor.hpp171
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/executors/loop_executor.hpp205
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/executors/scheduled_thread_pool.hpp48
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/executors/scheduler.hpp271
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/executors/scheduling_adaptor.hpp51
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/executors/serial_executor.hpp216
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/executors/serial_executor_cont.hpp170
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/executors/thread_executor.hpp157
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/executors/work.hpp30
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/experimental/config/inline_namespace.hpp23
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/experimental/exception_list.hpp16
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/experimental/parallel/v1/exception_list.hpp70
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/experimental/parallel/v1/inline_namespace.hpp28
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/experimental/parallel/v2/inline_namespace.hpp29
-rwxr-xr-xsrc/third_party/boost-1.60.0/boost/thread/experimental/parallel/v2/task_region.hpp316
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/experimental/task_region.hpp16
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/externally_locked.hpp351
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/externally_locked_stream.hpp170
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/future.hpp5552
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/futures/future_error.hpp98
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/futures/future_error_code.hpp61
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/futures/future_status.hpp30
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/futures/is_future_type.hpp21
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/futures/launch.hpp31
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/futures/wait_for_all.hpp74
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/futures/wait_for_any.hpp161
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/is_locked_by_this_thread.hpp39
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/latch.hpp170
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/lock_algorithms.hpp468
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/lock_concepts.hpp197
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/lock_factories.hpp78
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/lock_guard.hpp88
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/lock_options.hpp31
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/lock_traits.hpp45
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/lock_types.hpp1230
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/lockable_adapter.hpp226
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/lockable_concepts.hpp157
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/lockable_traits.hpp207
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/locks.hpp16
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/mutex.hpp53
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/null_mutex.hpp243
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/once.hpp44
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/ostream_buffer.hpp45
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/poly_lockable.hpp68
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/poly_lockable_adapter.hpp89
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/poly_shared_lockable.hpp135
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/poly_shared_lockable_adapter.hpp170
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/pthread/condition_variable.hpp428
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/pthread/condition_variable_fwd.hpp360
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/pthread/mutex.hpp361
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/pthread/once.hpp540
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/pthread/once_atomic.hpp313
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/pthread/pthread_mutex_scoped_lock.hpp64
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/pthread/recursive_mutex.hpp404
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/pthread/shared_mutex.hpp716
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/pthread/shared_mutex_assert.hpp724
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/pthread/thread_data.hpp292
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/pthread/thread_heap_alloc.hpp242
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/pthread/timespec.hpp120
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/recursive_mutex.hpp64
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/reverse_lock.hpp59
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/scoped_thread.hpp289
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/shared_lock_guard.hpp53
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/shared_mutex.hpp50
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/strict_lock.hpp235
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/sync_bounded_queue.hpp16
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/sync_queue.hpp16
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/synchronized_value.hpp1068
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/testable_mutex.hpp152
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/thread.hpp16
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/thread_functors.hpp57
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/thread_guard.hpp46
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/thread_only.hpp29
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/thread_pool.hpp15
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/thread_time.hpp55
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/tss.hpp113
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/user_scheduler.hpp202
-rwxr-xr-xsrc/third_party/boost-1.60.0/boost/thread/v2/shared_mutex.hpp1062
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/v2/thread.hpp155
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/win32/basic_recursive_mutex.hpp164
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/win32/basic_timed_mutex.hpp279
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/win32/condition_variable.hpp567
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/win32/interlocked_read.hpp77
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/win32/mfc_thread_init.hpp40
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/win32/mutex.hpp72
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/win32/once.hpp1087
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/win32/recursive_mutex.hpp70
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/win32/shared_mutex.hpp903
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/win32/thread_data.hpp328
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/win32/thread_heap_alloc.hpp409
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/win32/thread_primitives.hpp669
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/with_lock_guard.hpp234
-rw-r--r--src/third_party/boost-1.60.0/boost/thread/xtime.hpp93
161 files changed, 37372 insertions, 0 deletions
diff --git a/src/third_party/boost-1.60.0/boost/thread/barrier.hpp b/src/third_party/boost-1.60.0/boost/thread/barrier.hpp
new file mode 100644
index 00000000000..47daf07b352
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/barrier.hpp
@@ -0,0 +1,254 @@
+// Copyright (C) 2002-2003
+// David Moore, William E. Kempf
+// Copyright (C) 2007-8 Anthony Williams
+// (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)
+
+#ifndef BOOST_BARRIER_JDM030602_HPP
+#define BOOST_BARRIER_JDM030602_HPP
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/detail/delete.hpp>
+
+#include <boost/throw_exception.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/condition_variable.hpp>
+#include <string>
+#include <stdexcept>
+#include <boost/thread/detail/nullary_function.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/is_void.hpp>
+#include <boost/core/enable_if.hpp>
+#include <boost/utility/result_of.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ namespace thread_detail
+ {
+ typedef detail::nullary_function<void()> void_completion_function;
+ typedef detail::nullary_function<size_t()> size_completion_function;
+
+ struct default_barrier_reseter
+ {
+ unsigned int size_;
+ default_barrier_reseter(unsigned int size) :
+ size_(size)
+ {
+ }
+ BOOST_THREAD_MOVABLE(default_barrier_reseter)
+ //BOOST_THREAD_COPYABLE_AND_MOVABLE(default_barrier_reseter)
+
+ default_barrier_reseter(default_barrier_reseter const& other) BOOST_NOEXCEPT :
+ size_(other.size_)
+ {
+ }
+ default_barrier_reseter(BOOST_THREAD_RV_REF(default_barrier_reseter) other) BOOST_NOEXCEPT :
+ size_(BOOST_THREAD_RV(other).size_)
+ {
+ }
+
+ unsigned int operator()()
+ {
+ return size_;
+ }
+ };
+
+ struct void_functor_barrier_reseter
+ {
+ unsigned int size_;
+ void_completion_function fct_;
+ template <typename F>
+ void_functor_barrier_reseter(unsigned int size, BOOST_THREAD_RV_REF(F) funct)
+ : size_(size), fct_(boost::move(funct))
+ {}
+ template <typename F>
+ void_functor_barrier_reseter(unsigned int size, F& funct)
+ : size_(size), fct_(funct)
+ {}
+
+ BOOST_THREAD_MOVABLE(void_functor_barrier_reseter)
+ //BOOST_THREAD_COPYABLE_AND_MOVABLE(void_functor_barrier_reseter)
+
+ void_functor_barrier_reseter(void_functor_barrier_reseter const& other) BOOST_NOEXCEPT :
+ size_(other.size_), fct_(other.fct_)
+ {
+ }
+ void_functor_barrier_reseter(BOOST_THREAD_RV_REF(void_functor_barrier_reseter) other) BOOST_NOEXCEPT :
+ size_(BOOST_THREAD_RV(other).size_), fct_(BOOST_THREAD_RV(other).fct_)
+ //size_(BOOST_THREAD_RV(other).size_), fct_(boost::move(BOOST_THREAD_RV(other).fct_))
+ {
+ }
+
+ unsigned int operator()()
+ {
+ fct_();
+ return size_;
+ }
+ };
+ struct void_fct_ptr_barrier_reseter
+ {
+ unsigned int size_;
+ void(*fct_)();
+ void_fct_ptr_barrier_reseter(unsigned int size, void(*funct)()) :
+ size_(size), fct_(funct)
+ {
+ }
+ BOOST_THREAD_MOVABLE(void_fct_ptr_barrier_reseter)
+ //BOOST_THREAD_COPYABLE_AND_MOVABLE(void_fct_ptr_barrier_reseter)
+
+ void_fct_ptr_barrier_reseter(void_fct_ptr_barrier_reseter const& other) BOOST_NOEXCEPT :
+ size_(other.size_), fct_(other.fct_)
+ {
+ }
+ void_fct_ptr_barrier_reseter(BOOST_THREAD_RV_REF(void_fct_ptr_barrier_reseter) other) BOOST_NOEXCEPT :
+ size_(BOOST_THREAD_RV(other).size_), fct_(BOOST_THREAD_RV(other).fct_)
+ {
+ }
+ unsigned int operator()()
+ {
+ fct_();
+ return size_;
+ }
+ };
+ }
+ //BOOST_THREAD_DCL_MOVABLE(thread_detail::default_barrier_reseter)
+ //BOOST_THREAD_DCL_MOVABLE(thread_detail::void_functor_barrier_reseter)
+ //BOOST_THREAD_DCL_MOVABLE(thread_detail::void_fct_ptr_barrier_reseter)
+
+ class barrier
+ {
+ static inline unsigned int check_counter(unsigned int count)
+ {
+ if (count == 0) boost::throw_exception(
+ thread_exception(system::errc::invalid_argument, "barrier constructor: count cannot be zero."));
+ return count;
+ }
+ struct dummy
+ {
+ };
+
+ public:
+ BOOST_THREAD_NO_COPYABLE( barrier)
+
+ explicit barrier(unsigned int count) :
+ m_count(check_counter(count)), m_generation(0), fct_(BOOST_THREAD_MAKE_RV_REF(thread_detail::default_barrier_reseter(count)))
+ {
+ }
+
+ template <typename F>
+ barrier(
+ unsigned int count,
+ BOOST_THREAD_RV_REF(F) funct,
+ typename enable_if<
+ typename is_void<typename result_of<F>::type>::type, dummy*
+ >::type=0
+ )
+ : m_count(check_counter(count)),
+ m_generation(0),
+ fct_(BOOST_THREAD_MAKE_RV_REF(thread_detail::void_functor_barrier_reseter(count,
+ boost::move(funct)))
+ )
+ {
+ }
+ template <typename F>
+ barrier(
+ unsigned int count,
+ F &funct,
+ typename enable_if<
+ typename is_void<typename result_of<F>::type>::type, dummy*
+ >::type=0
+ )
+ : m_count(check_counter(count)),
+ m_generation(0),
+ fct_(BOOST_THREAD_MAKE_RV_REF(thread_detail::void_functor_barrier_reseter(count,
+ funct))
+ )
+ {
+ }
+
+ template <typename F>
+ barrier(
+ unsigned int count,
+ BOOST_THREAD_RV_REF(F) funct,
+ typename enable_if<
+ typename is_same<typename result_of<F>::type, unsigned int>::type, dummy*
+ >::type=0
+ )
+ : m_count(check_counter(count)),
+ m_generation(0),
+ fct_(boost::move(funct))
+ {
+ }
+ template <typename F>
+ barrier(
+ unsigned int count,
+ F& funct,
+ typename enable_if<
+ typename is_same<typename result_of<F>::type, unsigned int>::type, dummy*
+ >::type=0
+ )
+ : m_count(check_counter(count)),
+ m_generation(0),
+ fct_(funct)
+ {
+ }
+
+ barrier(unsigned int count, void(*funct)()) :
+ m_count(check_counter(count)), m_generation(0),
+ fct_(funct
+ ? BOOST_THREAD_MAKE_RV_REF(thread_detail::size_completion_function(BOOST_THREAD_MAKE_RV_REF(thread_detail::void_fct_ptr_barrier_reseter(count, funct))))
+ : BOOST_THREAD_MAKE_RV_REF(thread_detail::size_completion_function(BOOST_THREAD_MAKE_RV_REF(thread_detail::default_barrier_reseter(count))))
+ )
+ {
+ }
+ barrier(unsigned int count, unsigned int(*funct)()) :
+ m_count(check_counter(count)), m_generation(0),
+ fct_(funct
+ ? BOOST_THREAD_MAKE_RV_REF(thread_detail::size_completion_function(funct))
+ : BOOST_THREAD_MAKE_RV_REF(thread_detail::size_completion_function(BOOST_THREAD_MAKE_RV_REF(thread_detail::default_barrier_reseter(count))))
+ )
+ {
+ }
+
+ bool wait()
+ {
+ boost::unique_lock < boost::mutex > lock(m_mutex);
+ unsigned int gen = m_generation;
+
+ if (--m_count == 0)
+ {
+ m_generation++;
+ m_count = static_cast<unsigned int>(fct_());
+ BOOST_ASSERT(m_count != 0);
+ m_cond.notify_all();
+ return true;
+ }
+
+ while (gen == m_generation)
+ m_cond.wait(lock);
+ return false;
+ }
+
+ void count_down_and_wait()
+ {
+ wait();
+ }
+
+ private:
+ mutex m_mutex;
+ condition_variable m_cond;
+ unsigned int m_count;
+ unsigned int m_generation;
+ thread_detail::size_completion_function fct_;
+ };
+
+} // namespace boost
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/caller_context.hpp b/src/third_party/boost-1.60.0/boost/thread/caller_context.hpp
new file mode 100644
index 00000000000..dc50a05f975
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/caller_context.hpp
@@ -0,0 +1,59 @@
+// (C) Copyright 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)
+
+
+#ifndef BOOST_THREAD_CALL_CONTEXT_HPP
+#define BOOST_THREAD_CALL_CONTEXT_HPP
+
+#include <boost/thread/detail/config.hpp>
+#if defined BOOST_THREAD_USES_LOG_THREAD_ID
+#include <boost/thread/thread.hpp>
+#endif
+#include <boost/current_function.hpp>
+#include <boost/io/ios_state.hpp>
+#include <iomanip>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+
+ struct caller_context_t
+ {
+ const char * filename;
+ unsigned lineno;
+ const char * func;
+ caller_context_t(const char * filename, unsigned lineno, const char * func) :
+ filename(filename), lineno(lineno), func(func)
+ {
+ }
+ };
+
+#define BOOST_CONTEXTOF boost::caller_context_t(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION)
+
+ template <typename OStream>
+ OStream& operator<<(OStream& os, caller_context_t const& ctx)
+ {
+#if defined BOOST_THREAD_USES_LOG_THREAD_ID
+ {
+ io::ios_flags_saver ifs( os );
+ os << std::left << std::setw(14) << boost::this_thread::get_id() << " ";
+ }
+#endif
+ {
+ io::ios_flags_saver ifs(os);
+ os << std::setw(50) << ctx.filename << "["
+ << std::setw(4) << std::right << std::dec<< ctx.lineno << "] ";
+#if defined BOOST_THREAD_USES_LOG_CURRENT_FUNCTION
+ os << ctx.func << " " ;
+#endif
+ }
+ return os;
+ }
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/completion_latch.hpp b/src/third_party/boost-1.60.0/boost/thread/completion_latch.hpp
new file mode 100644
index 00000000000..ea76474276c
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/completion_latch.hpp
@@ -0,0 +1,226 @@
+// Distributed under the 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
+
+#ifndef BOOST_THREAD_COMPLETION_LATCH_HPP
+#define BOOST_THREAD_COMPLETION_LATCH_HPP
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/detail/delete.hpp>
+#include <boost/thread/detail/counter.hpp>
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/condition_variable.hpp>
+#include <boost/chrono/duration.hpp>
+#include <boost/chrono/time_point.hpp>
+#include <boost/assert.hpp>
+//#include <boost/thread/detail/nullary_function.hpp>
+#include <boost/thread/csbl/functional.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ namespace thread_detail
+ {
+ void noop()
+ {
+ }
+ }
+ class completion_latch
+ {
+ public:
+ /// the implementation defined completion function type
+ //typedef detail::nullary_function<void()> completion_function;
+ typedef csbl::function<void()> completion_function;
+ /// noop completion function factory
+ static completion_function noop()
+ {
+ return completion_function(&thread_detail::noop);
+ }
+
+ private:
+ struct around_wait;
+ friend struct around_wait;
+ struct around_wait
+ {
+ completion_latch &that_;
+ boost::unique_lock<boost::mutex> &lk_;
+ around_wait(completion_latch &that, boost::unique_lock<boost::mutex> &lk)
+ : that_(that), lk_(lk)
+ {
+ that_.leavers_.cond_.wait(lk, detail::counter_is_zero(that_.leavers_));
+ that_.waiters_.inc_and_notify_all();
+ that_.leavers_.cond_.wait(lk, detail::counter_is_not_zero(that_.leavers_));
+ }
+ ~around_wait()
+ {
+ that_.waiters_.dec_and_notify_all();
+ }
+ };
+
+ bool count_down(unique_lock<mutex> &lk)
+ {
+ BOOST_ASSERT(count_ > 0);
+ if (--count_ == 0)
+ {
+ waiters_.cond_.wait(lk, detail::counter_is_not_zero(waiters_));
+ leavers_.assign_and_notify_all(waiters_);
+ count_.cond_.notify_all();
+ waiters_.cond_.wait(lk, detail::counter_is_zero(waiters_));
+ leavers_.assign_and_notify_all(0);
+ lk.unlock();
+ funct_();
+ return true;
+ }
+ return false;
+ }
+
+ public:
+ BOOST_THREAD_NO_COPYABLE( completion_latch )
+
+ /// Constructs a latch with a given count.
+ completion_latch(std::size_t count) :
+ count_(count), funct_(noop()), waiters_(0), leavers_(0)
+ {
+ }
+
+ /// Constructs a latch with a given count and a completion function.
+ template <typename F>
+ completion_latch(std::size_t count, BOOST_THREAD_RV_REF(F) funct) :
+ count_(count),
+ funct_(boost::move(funct)),
+ waiters_(0),
+ leavers_(0)
+ {
+ }
+ template <typename F>
+ completion_latch(std::size_t count, void(*funct)()) :
+ count_(count), funct_(funct), waiters_(0), leavers_(0)
+ {
+ }
+
+ ///
+ ~completion_latch()
+ {
+ }
+
+ /// Blocks until the latch has counted down to zero.
+ void wait()
+ {
+ boost::unique_lock<boost::mutex> lk(mutex_);
+ around_wait aw(*this, lk);
+ count_.cond_.wait(lk, detail::counter_is_zero(count_));
+ }
+
+ /// @return true if the internal counter is already 0, false otherwise
+ bool try_wait()
+ {
+ boost::unique_lock<boost::mutex> lk(mutex_);
+ around_wait aw(*this, lk);
+ return (count_ == 0);
+ }
+
+ /// try to wait for a specified amount of time
+ /// @return whether there is a timeout or not.
+ template <class Rep, class Period>
+ cv_status wait_for(const chrono::duration<Rep, Period>& rel_time)
+ {
+ boost::unique_lock<boost::mutex> lk(mutex_);
+ around_wait aw(*this, lk);
+ return count_.cond_.wait_for(lk, rel_time, detail::counter_is_zero(count_))
+ ? cv_status::no_timeout
+ : cv_status::timeout;
+ }
+
+ /// try to wait until the specified time_point is reached
+ /// @return whether there is a timeout or not.
+ template <class Clock, class Duration>
+ cv_status wait_until(const chrono::time_point<Clock, Duration>& abs_time)
+ {
+ boost::unique_lock<boost::mutex> lk(mutex_);
+ around_wait aw(*this, lk);
+ return count_.cond_.wait_until(lk, abs_time, detail::counter_is_zero(count_))
+ ? cv_status::no_timeout
+ : cv_status::timeout;
+ }
+
+ /// Decrement the count and notify anyone waiting if we reach zero.
+ /// @Requires count must be greater than 0
+ void count_down()
+ {
+ unique_lock<mutex> lk(mutex_);
+ count_down(lk);
+ }
+ void signal()
+ {
+ count_down();
+ }
+
+ /// Decrement the count and notify anyone waiting if we reach zero.
+ /// Blocks until the latch has counted down to zero.
+ /// @Requires count must be greater than 0
+ void count_down_and_wait()
+ {
+ boost::unique_lock<boost::mutex> lk(mutex_);
+ if (count_down(lk))
+ {
+ return;
+ }
+ around_wait aw(*this, lk);
+ count_.cond_.wait(lk, detail::counter_is_zero(count_));
+ }
+ void sync()
+ {
+ count_down_and_wait();
+ }
+
+ /// Reset the counter
+ /// #Requires This method may only be invoked when there are no other threads currently inside the count_down_and_wait() method.
+ void reset(std::size_t count)
+ {
+ boost::lock_guard<boost::mutex> lk(mutex_);
+ //BOOST_ASSERT(count_ == 0);
+ count_ = count;
+ }
+
+ /// Resets the latch with the new completion function.
+ /// The next time the internal count reaches 0, this function will be invoked.
+ /// This completion function may only be invoked when there are no other threads
+ /// currently inside the count_down and wait related functions.
+ /// It may also be invoked from within the registered completion function.
+ /// @Returns the old completion function if any or noop if
+
+#ifdef BOOST_NO_CXX11_HDR_FUNCTIONAL
+ template <typename F>
+ completion_function then(BOOST_THREAD_RV_REF(F) funct)
+ {
+ boost::lock_guard<boost::mutex> lk(mutex_);
+ completion_function tmp(funct_);
+ funct_ = boost::move(funct);
+ return tmp;
+ }
+#endif
+ completion_function then(void(*funct)())
+ {
+ boost::lock_guard<boost::mutex> lk(mutex_);
+ completion_function tmp(funct_);
+ funct_ = completion_function(funct);
+ return tmp;
+ }
+
+ private:
+ mutex mutex_;
+ detail::counter count_;
+ completion_function funct_;
+ detail::counter waiters_;
+ detail::counter leavers_;
+ };
+
+} // namespace boost
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/deque_adaptor.hpp b/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/deque_adaptor.hpp
new file mode 100644
index 00000000000..a8f45f863f4
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/deque_adaptor.hpp
@@ -0,0 +1,209 @@
+#ifndef BOOST_THREAD_CONCURRENT_DEQUE_ADAPTOR_HPP
+#define BOOST_THREAD_CONCURRENT_DEQUE_ADAPTOR_HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2014. Distributed under the 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 http://www.boost.org/libs/thread for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/concurrent_queues/queue_op_status.hpp>
+#include <boost/thread/concurrent_queues/deque_base.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+namespace concurrent
+{
+namespace detail
+{
+
+ template <typename Queue>
+ class deque_adaptor_copyable_only :
+ public boost::deque_base<typename Queue::value_type, typename Queue::size_type>
+ {
+ Queue queue;
+ public:
+ typedef typename Queue::value_type value_type;
+ typedef typename Queue::size_type size_type;
+
+ // Constructors/Assignment/Destructors
+ deque_adaptor_copyable_only() {}
+
+ // Observers
+ bool empty() const { return queue.empty(); }
+ bool full() const { return queue.full(); }
+ size_type size() const { return queue.size(); }
+ bool closed() const { return queue.closed(); }
+
+ // Modifiers
+ void close() { queue.close(); }
+
+ void push_back(const value_type& x) { queue.push_back(x); }
+
+ void pull_front(value_type& x) { queue.pull_front(x); };
+ value_type pull_front() { return queue.pull_front(); }
+
+ queue_op_status try_push_back(const value_type& x) { return queue.try_push_back(x); }
+ queue_op_status try_pull_front(value_type& x) { return queue.try_pull_front(x); }
+
+ queue_op_status nonblocking_push_back(const value_type& x) { return queue.nonblocking_push_back(x); }
+ queue_op_status nonblocking_pull_front(value_type& x) { return queue.nonblocking_pull_front(x); }
+
+ queue_op_status wait_push_back(const value_type& x) { return queue.wait_push_back(x); }
+ queue_op_status wait_pull_front(value_type& x) { return queue.wait_pull_front(x); }
+
+ };
+ template <typename Queue>
+ class deque_adaptor_movable_only :
+ public boost::deque_base<typename Queue::value_type, typename Queue::size_type>
+ {
+ Queue queue;
+ public:
+ typedef typename Queue::value_type value_type;
+ typedef typename Queue::size_type size_type;
+
+ // Constructors/Assignment/Destructors
+
+ deque_adaptor_movable_only() {}
+
+ // Observers
+ bool empty() const { return queue.empty(); }
+ bool full() const { return queue.full(); }
+ size_type size() const { return queue.size(); }
+ bool closed() const { return queue.closed(); }
+
+ // Modifiers
+ void close() { queue.close(); }
+
+
+ void pull_front(value_type& x) { queue.pull_front(x); };
+ // enable_if is_nothrow_copy_movable<value_type>
+ value_type pull_front() { return queue.pull_front(); }
+
+ queue_op_status try_pull_front(value_type& x) { return queue.try_pull_front(x); }
+
+ queue_op_status nonblocking_pull_front(value_type& x) { return queue.nonblocking_pull_front(x); }
+
+ queue_op_status wait_pull_front(value_type& x) { return queue.wait_pull_front(x); }
+
+ void push_back(BOOST_THREAD_RV_REF(value_type) x) { queue.push_back(boost::move(x)); }
+ queue_op_status try_push_back(BOOST_THREAD_RV_REF(value_type) x) { return queue.try_push_back(boost::move(x)); }
+ queue_op_status nonblocking_push_back(BOOST_THREAD_RV_REF(value_type) x) { return queue.nonblocking_push_back(boost::move(x)); }
+ queue_op_status wait_push_back(BOOST_THREAD_RV_REF(value_type) x) { return queue.wait_push_back(boost::move(x)); }
+ };
+
+ template <typename Queue>
+ class deque_adaptor_copyable_and_movable :
+ public boost::deque_base<typename Queue::value_type, typename Queue::size_type>
+ {
+ Queue queue;
+ public:
+ typedef typename Queue::value_type value_type;
+ typedef typename Queue::size_type size_type;
+
+ // Constructors/Assignment/Destructors
+
+ deque_adaptor_copyable_and_movable() {}
+
+ // Observers
+ bool empty() const { return queue.empty(); }
+ bool full() const { return queue.full(); }
+ size_type size() const { return queue.size(); }
+ bool closed() const { return queue.closed(); }
+
+ // Modifiers
+ void close() { queue.close(); }
+
+
+ void push_back(const value_type& x) { queue.push_back(x); }
+
+ void pull_front(value_type& x) { queue.pull_front(x); };
+ // enable_if is_nothrow_copy_movable<value_type>
+ value_type pull_front() { return queue.pull_front(); }
+
+ queue_op_status try_push_back(const value_type& x) { return queue.try_push_back(x); }
+ queue_op_status try_pull_front(value_type& x) { return queue.try_pull_front(x); }
+
+ queue_op_status nonblocking_push_back(const value_type& x) { return queue.nonblocking_push_back(x); }
+ queue_op_status nonblocking_pull_front(value_type& x) { return queue.nonblocking_pull_front(x); }
+
+ queue_op_status wait_push_back(const value_type& x) { return queue.wait_push_back(x); }
+ queue_op_status wait_pull_front(value_type& x) { return queue.wait_pull_front(x); }
+
+ void push_back(BOOST_THREAD_RV_REF(value_type) x) { queue.push_back(boost::move(x)); }
+ queue_op_status try_push_back(BOOST_THREAD_RV_REF(value_type) x) { return queue.try_push_back(boost::move(x)); }
+ queue_op_status nonblocking_push_back(BOOST_THREAD_RV_REF(value_type) x) { return queue.nonblocking_push_back(boost::move(x)); }
+ queue_op_status wait_push_back(BOOST_THREAD_RV_REF(value_type) x) { return queue.wait_push_back(boost::move(x)); }
+ };
+
+
+ template <class Q, class T,
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+#if defined __GNUC__ && ! defined __clang__
+#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5) || !defined(__GXX_EXPERIMENTAL_CXX0X__)
+ bool Copyable = is_copy_constructible<T>::value,
+ bool Movable = true
+#else
+ bool Copyable = std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value,
+ bool Movable = std::is_move_constructible<T>::value && std::is_move_assignable<T>::value
+#endif // __GNUC__
+#elif defined _MSC_VER
+#if _MSC_VER < 1700
+ bool Copyable = is_copy_constructible<T>::value,
+ bool Movable = true
+#else
+ bool Copyable = std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value,
+ bool Movable = std::is_move_constructible<T>::value && std::is_move_assignable<T>::value
+#endif // _MSC_VER
+#else
+ bool Copyable = std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value,
+ bool Movable = std::is_move_constructible<T>::value && std::is_move_assignable<T>::value
+#endif
+#else
+ bool Copyable = is_copy_constructible<T>::value,
+ bool Movable = has_move_emulation_enabled<T>::value
+#endif
+ >
+ struct deque_adaptor;
+
+ template <class Q, class T>
+ struct deque_adaptor<Q, T, true, true> {
+ typedef deque_adaptor_copyable_and_movable<Q> type;
+ };
+ template <class Q, class T>
+ struct deque_adaptor<Q, T, true, false> {
+ typedef deque_adaptor_copyable_only<Q> type;
+ };
+ template <class Q, class T>
+ struct deque_adaptor<Q, T, false, true> {
+ typedef deque_adaptor_movable_only<Q> type;
+ };
+
+}
+
+ template <typename Queue>
+ class deque_adaptor :
+ public detail::deque_adaptor<Queue, typename Queue::value_type>::type
+ {
+ public:
+ typedef typename Queue::value_type value_type;
+ typedef typename Queue::size_type size_type;
+ // Constructors/Assignment/Destructors
+ virtual ~deque_adaptor() {};
+ };
+}
+using concurrent::deque_adaptor;
+
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/deque_base.hpp b/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/deque_base.hpp
new file mode 100644
index 00000000000..f76e8a761dd
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/deque_base.hpp
@@ -0,0 +1,202 @@
+#ifndef BOOST_THREAD_CONCURRENT_DEQUE_BASE_HPP
+#define BOOST_THREAD_CONCURRENT_DEQUE_BASE_HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2014. Distributed under the 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 http://www.boost.org/libs/thread for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/concurrent_queues/queue_op_status.hpp>
+#include <boost/type_traits/conditional.hpp>
+#include <boost/type_traits/is_copy_constructible.hpp>
+
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+namespace concurrent
+{
+namespace detail
+{
+
+ template <typename ValueType, class SizeType>
+ class deque_base_copyable_only
+ {
+ public:
+ typedef ValueType value_type;
+ typedef SizeType size_type;
+
+ // Constructors/Assignment/Destructors
+ virtual ~deque_base_copyable_only() {};
+
+ // Observers
+ virtual bool empty() const = 0;
+ virtual bool full() const = 0;
+ virtual size_type size() const = 0;
+ virtual bool closed() const = 0;
+
+ // Modifiers
+ virtual void close() = 0;
+
+ virtual void push_back(const value_type& x) = 0;
+
+ virtual void pull_front(value_type&) = 0;
+ virtual value_type pull_front() = 0;
+
+ virtual queue_op_status try_push_back(const value_type& x) = 0;
+ virtual queue_op_status try_pull_front(value_type&) = 0;
+
+ virtual queue_op_status nonblocking_push_back(const value_type& x) = 0;
+ virtual queue_op_status nonblocking_pull_front(value_type&) = 0;
+
+ virtual queue_op_status wait_push_back(const value_type& x) = 0;
+ virtual queue_op_status wait_pull_front(value_type& elem) = 0;
+
+ };
+
+ template <typename ValueType, class SizeType>
+ class deque_base_movable_only
+ {
+ public:
+ typedef ValueType value_type;
+ typedef SizeType size_type;
+ // Constructors/Assignment/Destructors
+ virtual ~deque_base_movable_only() {};
+
+ // Observers
+ virtual bool empty() const = 0;
+ virtual bool full() const = 0;
+ virtual size_type size() const = 0;
+ virtual bool closed() const = 0;
+
+ // Modifiers
+ virtual void close() = 0;
+
+ virtual void pull_front(value_type&) = 0;
+ // enable_if is_nothrow_movable<value_type>
+ virtual value_type pull_front() = 0;
+
+ virtual queue_op_status try_pull_front(value_type&) = 0;
+
+ virtual queue_op_status nonblocking_pull_front(value_type&) = 0;
+
+ virtual queue_op_status wait_pull_front(value_type& elem) = 0;
+
+ virtual void push_back(BOOST_THREAD_RV_REF(value_type) x) = 0;
+ virtual queue_op_status try_push_back(BOOST_THREAD_RV_REF(value_type) x) = 0;
+ virtual queue_op_status nonblocking_push_back(BOOST_THREAD_RV_REF(value_type) x) = 0;
+ virtual queue_op_status wait_push_back(BOOST_THREAD_RV_REF(value_type) x) = 0;
+ };
+
+
+ template <typename ValueType, class SizeType>
+ class deque_base_copyable_and_movable
+ {
+ public:
+ typedef ValueType value_type;
+ typedef SizeType size_type;
+ // Constructors/Assignment/Destructors
+ virtual ~deque_base_copyable_and_movable() {};
+
+
+ // Observers
+ virtual bool empty() const = 0;
+ virtual bool full() const = 0;
+ virtual size_type size() const = 0;
+ virtual bool closed() const = 0;
+
+ // Modifiers
+ virtual void close() = 0;
+
+ virtual void push_back(const value_type& x) = 0;
+
+ virtual void pull_front(value_type&) = 0;
+ // enable_if is_nothrow_copy_movable<value_type>
+ virtual value_type pull_front() = 0;
+
+ virtual queue_op_status try_push_back(const value_type& x) = 0;
+ virtual queue_op_status try_pull_front(value_type&) = 0;
+
+ virtual queue_op_status nonblocking_push_back(const value_type& x) = 0;
+ virtual queue_op_status nonblocking_pull_front(value_type&) = 0;
+
+ virtual queue_op_status wait_push_back(const value_type& x) = 0;
+ virtual queue_op_status wait_pull_front(value_type& elem) = 0;
+
+ virtual void push_back(BOOST_THREAD_RV_REF(value_type) x) = 0;
+ virtual queue_op_status try_push_back(BOOST_THREAD_RV_REF(value_type) x) = 0;
+ virtual queue_op_status nonblocking_push_back(BOOST_THREAD_RV_REF(value_type) x) = 0;
+ virtual queue_op_status wait_push_back(BOOST_THREAD_RV_REF(value_type) x) = 0;
+ };
+
+ template <class T, class ST,
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+#if defined __GNUC__ && ! defined __clang__
+#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5) || !defined(__GXX_EXPERIMENTAL_CXX0X__)
+ bool Copyable = is_copy_constructible<T>::value,
+ bool Movable = true
+#else
+ bool Copyable = std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value,
+ bool Movable = std::is_move_constructible<T>::value && std::is_move_assignable<T>::value
+#endif // __GNUC__
+#elif defined _MSC_VER
+#if _MSC_VER < 1700
+ bool Copyable = is_copy_constructible<T>::value,
+ bool Movable = true
+#else
+ bool Copyable = std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value,
+ bool Movable = std::is_move_constructible<T>::value && std::is_move_assignable<T>::value
+#endif // _MSC_VER
+#else
+ bool Copyable = std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value,
+ bool Movable = std::is_move_constructible<T>::value && std::is_move_assignable<T>::value
+#endif
+#else
+ bool Copyable = is_copy_constructible<T>::value,
+ bool Movable = has_move_emulation_enabled<T>::value
+#endif
+ >
+ struct deque_base;
+
+ template <class T, class ST>
+ struct deque_base<T, ST, true, true> {
+ typedef deque_base_copyable_and_movable<T, ST> type;
+ };
+ template <class T, class ST>
+ struct deque_base<T, ST, true, false> {
+ typedef deque_base_copyable_only<T, ST> type;
+ };
+ template <class T, class ST>
+ struct deque_base<T, ST, false, true> {
+ typedef deque_base_movable_only<T, ST> type;
+ };
+
+}
+
+ template <class ValueType, class SizeType=std::size_t>
+ class deque_base :
+ public detail::deque_base<ValueType, SizeType>::type
+ {
+ public:
+ typedef ValueType value_type;
+ typedef SizeType size_type;
+ // Constructors/Assignment/Destructors
+ virtual ~deque_base() {};
+ };
+
+}
+using concurrent::deque_base;
+
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/deque_views.hpp b/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/deque_views.hpp
new file mode 100644
index 00000000000..5715fb88cff
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/deque_views.hpp
@@ -0,0 +1,165 @@
+#ifndef BOOST_THREAD_QUEUE_VIEWS_HPP
+#define BOOST_THREAD_QUEUE_VIEWS_HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2014. Distributed under the 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 http://www.boost.org/libs/thread for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/concurrent_queues/queue_op_status.hpp>
+#include <boost/thread/concurrent_queues/deque_base.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+namespace concurrent
+{
+
+ template <typename Queue>
+ class deque_back_view
+ {
+ Queue* queue;
+ public:
+ typedef typename Queue::value_type value_type;
+ typedef typename Queue::size_type size_type;
+
+ // Constructors/Assignment/Destructors
+ deque_back_view(Queue& q) BOOST_NOEXCEPT : queue(&q) {}
+
+ // Observers
+ bool empty() const { return queue->empty(); }
+ bool full() const { return queue->full(); }
+ size_type size() const { return queue->size(); }
+ bool closed() const { return queue->closed(); }
+
+ // Modifiers
+ void close() { queue->close(); }
+
+ void push(const value_type& x) { queue->push_back(x); }
+
+ void pull(value_type& x) { queue->pull_back(x); }
+ // enable_if is_nothrow_copy_movable<value_type>
+ value_type pull() { return queue->pull_back(); }
+
+ queue_op_status try_push(const value_type& x) { return queue->try_push_back(x); }
+
+ queue_op_status try_pull(value_type& x) { return queue->try_pull_back(x); }
+
+ queue_op_status nonblocking_push(const value_type& x) { return queue->nonblocking_push_back(x); }
+
+ queue_op_status nonblocking_pull(value_type& x) { return queue->nonblocking_pull_back(x); }
+
+ queue_op_status wait_push(const value_type& x) { return queue->wait_push_back(x); }
+ queue_op_status wait_pull(value_type& x) { return queue->wait_pull_back(x); }
+
+ void push(BOOST_THREAD_RV_REF(value_type) x) { queue->push_back(boost::move(x)); }
+ queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->try_push_back(boost::move(x)); }
+ queue_op_status nonblocking_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->nonblocking_push_back(boost::move(x)); }
+ queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->wait_push_back(boost::move(x)); }
+ };
+
+ template <typename Queue>
+ class deque_front_view
+ {
+ Queue* queue;
+ public:
+ typedef typename Queue::value_type value_type;
+ typedef typename Queue::size_type size_type;
+
+ // Constructors/Assignment/Destructors
+ deque_front_view(Queue& q) BOOST_NOEXCEPT : queue(&q) {}
+
+ // Observers
+ bool empty() const { return queue->empty(); }
+ bool full() const { return queue->full(); }
+ size_type size() const { return queue->size(); }
+ bool closed() const { return queue->closed(); }
+
+ // Modifiers
+ void close() { queue->close(); }
+
+ void push(const value_type& x) { queue->push_front(x); }
+
+ void pull(value_type& x) { queue->pull_front(x); };
+ // enable_if is_nothrow_copy_movable<value_type>
+ value_type pull() { return queue->pull_front(); }
+
+ queue_op_status try_push(const value_type& x) { return queue->try_push_front(x); }
+
+ queue_op_status try_pull(value_type& x) { return queue->try_pull_front(x); }
+
+ queue_op_status nonblocking_push(const value_type& x) { return queue->nonblocking_push_front(x); }
+
+ queue_op_status nonblocking_pull(value_type& x) { return queue->nonblocking_pull_front(x); }
+
+ queue_op_status wait_push(const value_type& x) { return queue->wait_push_front(x); }
+ queue_op_status wait_pull(value_type& x) { return queue->wait_pull_front(x); }
+ void push(BOOST_THREAD_RV_REF(value_type) x) { queue->push_front(forward<value_type>(x)); }
+ queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->try_push_front(forward<value_type>(x)); }
+ queue_op_status nonblocking_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->nonblocking_push_front(forward<value_type>(x)); }
+ queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->wait_push_front(forward<value_type>(x)); }
+
+ };
+
+#if ! defined BOOST_NO_CXX11_TEMPLATE_ALIASES
+
+ template <class T>
+ using deque_back = deque_back_view<deque_base<T> > ;
+ template <class T>
+ using deque_front = deque_front_view<deque_base<T> > ;
+
+#else
+
+ template <class T>
+ struct deque_back : deque_back_view<deque_base<T> >
+ {
+ typedef deque_back_view<deque_base<T> > base_type;
+ deque_back(deque_base<T>& q) BOOST_NOEXCEPT : base_type(q) {}
+ };
+ template <class T>
+ struct deque_front : deque_front_view<deque_base<T> >
+ {
+ typedef deque_front_view<deque_base<T> > base_type;
+ deque_front(deque_base<T>& q) BOOST_NOEXCEPT : base_type(q) {}
+
+ };
+
+#endif
+
+// template <class Queue>
+// deque_back_view<Queue> back(Queue & q) { return deque_back_view<Queue>(q); }
+// template <class Queue>
+// deque_front_view<Queue> front(Queue & q) { return deque_front_view<Queue>(q); }
+//#if 0
+// template <class T>
+// deque_back<T> back(deque_base<T> & q) { return deque_back<T>(q); }
+// template <class T>
+// deque_front<T> front(deque_base<T> & q) { return deque_front<T>(q); }
+//#else
+// template <class T>
+// typename deque_back<T>::type back(deque_base<T> & q) { return typename deque_back<T>::type(q); }
+// template <class T>
+// typename deque_front<T>::type front(deque_base<T> & q) { return typename deque_front<T>::type(q); }
+//#endif
+}
+
+using concurrent::deque_back_view;
+using concurrent::deque_front_view;
+using concurrent::deque_back;
+using concurrent::deque_front;
+//using concurrent::back;
+//using concurrent::front;
+
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/detail/sync_deque_base.hpp b/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/detail/sync_deque_base.hpp
new file mode 100644
index 00000000000..877e1e2eb40
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/detail/sync_deque_base.hpp
@@ -0,0 +1,223 @@
+#ifndef BOOST_THREAD_CONCURRENT_QUEUES_DETAIL_SYNC_DEQUE_BASE_HPP
+#define BOOST_THREAD_CONCURRENT_QUEUES_DETAIL_SYNC_DEQUE_BASE_HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2013-2014. Distributed under the 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 http://www.boost.org/libs/thread for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/concurrent_queues/queue_op_status.hpp>
+
+#include <boost/chrono/duration.hpp>
+#include <boost/chrono/time_point.hpp>
+#include <boost/chrono/system_clocks.hpp>
+#include <boost/throw_exception.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+namespace concurrent
+{
+namespace detail
+{
+
+ template <class ValueType, class Queue>
+ class sync_deque_base
+ {
+ public:
+ typedef ValueType value_type;
+ typedef Queue underlying_queue_type;
+ typedef typename Queue::size_type size_type;
+ typedef queue_op_status op_status;
+
+ typedef typename chrono::steady_clock clock;
+ typedef typename clock::duration duration;
+ typedef typename clock::time_point time_point;
+
+ // Constructors/Assignment/Destructors
+ BOOST_THREAD_NO_COPYABLE(sync_deque_base)
+ inline sync_deque_base();
+ //template <typename Range>
+ //inline explicit sync_deque(Range range);
+ inline ~sync_deque_base();
+
+ // Observers
+ inline bool empty() const;
+ inline bool full() const;
+ inline size_type size() const;
+ inline bool closed() const;
+
+ // Modifiers
+ inline void close();
+
+ inline underlying_queue_type underlying_queue() {
+ lock_guard<mutex> lk(mtx_);
+ return boost::move(data_);
+ }
+
+ protected:
+ mutable mutex mtx_;
+ condition_variable not_empty_;
+ underlying_queue_type data_;
+ bool closed_;
+
+ inline bool empty(unique_lock<mutex>& ) const BOOST_NOEXCEPT
+ {
+ return data_.empty();
+ }
+ inline bool empty(lock_guard<mutex>& ) const BOOST_NOEXCEPT
+ {
+ return data_.empty();
+ }
+
+ inline size_type size(lock_guard<mutex>& ) const BOOST_NOEXCEPT
+ {
+ return data_.size();
+ }
+ inline bool closed(unique_lock<mutex>& lk) const;
+ inline bool closed(lock_guard<mutex>& lk) const;
+
+ inline void throw_if_closed(unique_lock<mutex>&);
+ inline void throw_if_closed(lock_guard<mutex>&);
+
+ inline void wait_until_not_empty(unique_lock<mutex>& lk);
+ inline bool wait_until_not_empty_or_closed(unique_lock<mutex>& lk);
+ inline queue_op_status wait_until_not_empty_until(unique_lock<mutex>& lk, time_point const&);
+
+ inline void notify_not_empty_if_needed(unique_lock<mutex>& )
+ {
+ not_empty_.notify_one();
+ }
+ inline void notify_not_empty_if_needed(lock_guard<mutex>& )
+ {
+ not_empty_.notify_one();
+ }
+
+ };
+
+ template <class ValueType, class Queue>
+ sync_deque_base<ValueType, Queue>::sync_deque_base() :
+ data_(), closed_(false)
+ {
+ BOOST_ASSERT(data_.empty());
+ }
+
+ template <class ValueType, class Queue>
+ sync_deque_base<ValueType, Queue>::~sync_deque_base()
+ {
+ }
+
+ template <class ValueType, class Queue>
+ void sync_deque_base<ValueType, Queue>::close()
+ {
+ {
+ lock_guard<mutex> lk(mtx_);
+ closed_ = true;
+ }
+ not_empty_.notify_all();
+ }
+
+ template <class ValueType, class Queue>
+ bool sync_deque_base<ValueType, Queue>::closed() const
+ {
+ lock_guard<mutex> lk(mtx_);
+ return closed(lk);
+ }
+ template <class ValueType, class Queue>
+ bool sync_deque_base<ValueType, Queue>::closed(unique_lock<mutex>&) const
+ {
+ return closed_;
+ }
+ template <class ValueType, class Queue>
+ bool sync_deque_base<ValueType, Queue>::closed(lock_guard<mutex>&) const
+ {
+ return closed_;
+ }
+
+ template <class ValueType, class Queue>
+ bool sync_deque_base<ValueType, Queue>::empty() const
+ {
+ lock_guard<mutex> lk(mtx_);
+ return empty(lk);
+ }
+ template <class ValueType, class Queue>
+ bool sync_deque_base<ValueType, Queue>::full() const
+ {
+ return false;
+ }
+
+ template <class ValueType, class Queue>
+ typename sync_deque_base<ValueType, Queue>::size_type sync_deque_base<ValueType, Queue>::size() const
+ {
+ lock_guard<mutex> lk(mtx_);
+ return size(lk);
+ }
+
+ template <class ValueType, class Queue>
+ void sync_deque_base<ValueType, Queue>::throw_if_closed(unique_lock<mutex>& lk)
+ {
+ if (closed(lk))
+ {
+ BOOST_THROW_EXCEPTION( sync_deque_is_closed() );
+ }
+ }
+ template <class ValueType, class Queue>
+ void sync_deque_base<ValueType, Queue>::throw_if_closed(lock_guard<mutex>& lk)
+ {
+ if (closed(lk))
+ {
+ BOOST_THROW_EXCEPTION( sync_deque_is_closed() );
+ }
+ }
+
+ template <class ValueType, class Queue>
+ void sync_deque_base<ValueType, Queue>::wait_until_not_empty(unique_lock<mutex>& lk)
+ {
+ for (;;)
+ {
+ if (! empty(lk)) break;
+ throw_if_closed(lk);
+ not_empty_.wait(lk);
+ }
+ }
+ template <class ValueType, class Queue>
+ bool sync_deque_base<ValueType, Queue>::wait_until_not_empty_or_closed(unique_lock<mutex>& lk)
+ {
+ for (;;)
+ {
+ if (! empty(lk)) break;
+ if (closed(lk)) return true;
+ not_empty_.wait(lk);
+ }
+ return false;
+ }
+
+ template <class ValueType, class Queue>
+ queue_op_status sync_deque_base<ValueType, Queue>::wait_until_not_empty_until(unique_lock<mutex>& lk, time_point const&tp)
+ {
+ for (;;)
+ {
+ if (! empty(lk)) return queue_op_status::success;
+ throw_if_closed(lk);
+ if (not_empty_.wait_until(lk, tp) == cv_status::timeout ) return queue_op_status::timeout;
+ }
+ }
+
+
+} // detail
+} // concurrent
+} // boost
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/detail/sync_queue_base.hpp b/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/detail/sync_queue_base.hpp
new file mode 100644
index 00000000000..653e273f8b8
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/detail/sync_queue_base.hpp
@@ -0,0 +1,223 @@
+#ifndef BOOST_THREAD_CONCURRENT_QUEUES_DETAIL_SYNC_QUEUE_BASE_HPP
+#define BOOST_THREAD_CONCURRENT_QUEUES_DETAIL_SYNC_QUEUE_BASE_HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2013-2014. Distributed under the 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 http://www.boost.org/libs/thread for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/concurrent_queues/queue_op_status.hpp>
+
+#include <boost/chrono/duration.hpp>
+#include <boost/chrono/time_point.hpp>
+#include <boost/chrono/system_clocks.hpp>
+#include <boost/throw_exception.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+namespace concurrent
+{
+namespace detail
+{
+
+ template <class ValueType, class Queue>
+ class sync_queue_base
+ {
+ public:
+ typedef ValueType value_type;
+ typedef Queue underlying_queue_type;
+ typedef typename Queue::size_type size_type;
+ typedef queue_op_status op_status;
+
+ typedef typename chrono::steady_clock clock;
+ typedef typename clock::duration duration;
+ typedef typename clock::time_point time_point;
+
+ // Constructors/Assignment/Destructors
+ BOOST_THREAD_NO_COPYABLE(sync_queue_base)
+ inline sync_queue_base();
+ //template <typename Range>
+ //inline explicit sync_queue(Range range);
+ inline ~sync_queue_base();
+
+ // Observers
+ inline bool empty() const;
+ inline bool full() const;
+ inline size_type size() const;
+ inline bool closed() const;
+
+ // Modifiers
+ inline void close();
+
+ inline underlying_queue_type underlying_queue() {
+ lock_guard<mutex> lk(mtx_);
+ return boost::move(data_);
+ }
+
+ protected:
+ mutable mutex mtx_;
+ condition_variable not_empty_;
+ underlying_queue_type data_;
+ bool closed_;
+
+ inline bool empty(unique_lock<mutex>& ) const BOOST_NOEXCEPT
+ {
+ return data_.empty();
+ }
+ inline bool empty(lock_guard<mutex>& ) const BOOST_NOEXCEPT
+ {
+ return data_.empty();
+ }
+
+ inline size_type size(lock_guard<mutex>& ) const BOOST_NOEXCEPT
+ {
+ return data_.size();
+ }
+ inline bool closed(unique_lock<mutex>& lk) const;
+ inline bool closed(lock_guard<mutex>& lk) const;
+
+ inline void throw_if_closed(unique_lock<mutex>&);
+ inline void throw_if_closed(lock_guard<mutex>&);
+
+ inline void wait_until_not_empty(unique_lock<mutex>& lk);
+ inline bool wait_until_not_empty_or_closed(unique_lock<mutex>& lk);
+ inline queue_op_status wait_until_not_empty_until(unique_lock<mutex>& lk, time_point const&);
+
+ inline void notify_not_empty_if_needed(unique_lock<mutex>& )
+ {
+ not_empty_.notify_one();
+ }
+ inline void notify_not_empty_if_needed(lock_guard<mutex>& )
+ {
+ not_empty_.notify_one();
+ }
+
+ };
+
+ template <class ValueType, class Queue>
+ sync_queue_base<ValueType, Queue>::sync_queue_base() :
+ data_(), closed_(false)
+ {
+ BOOST_ASSERT(data_.empty());
+ }
+
+ template <class ValueType, class Queue>
+ sync_queue_base<ValueType, Queue>::~sync_queue_base()
+ {
+ }
+
+ template <class ValueType, class Queue>
+ void sync_queue_base<ValueType, Queue>::close()
+ {
+ {
+ lock_guard<mutex> lk(mtx_);
+ closed_ = true;
+ }
+ not_empty_.notify_all();
+ }
+
+ template <class ValueType, class Queue>
+ bool sync_queue_base<ValueType, Queue>::closed() const
+ {
+ lock_guard<mutex> lk(mtx_);
+ return closed(lk);
+ }
+ template <class ValueType, class Queue>
+ bool sync_queue_base<ValueType, Queue>::closed(unique_lock<mutex>&) const
+ {
+ return closed_;
+ }
+ template <class ValueType, class Queue>
+ bool sync_queue_base<ValueType, Queue>::closed(lock_guard<mutex>&) const
+ {
+ return closed_;
+ }
+
+ template <class ValueType, class Queue>
+ bool sync_queue_base<ValueType, Queue>::empty() const
+ {
+ lock_guard<mutex> lk(mtx_);
+ return empty(lk);
+ }
+ template <class ValueType, class Queue>
+ bool sync_queue_base<ValueType, Queue>::full() const
+ {
+ return false;
+ }
+
+ template <class ValueType, class Queue>
+ typename sync_queue_base<ValueType, Queue>::size_type sync_queue_base<ValueType, Queue>::size() const
+ {
+ lock_guard<mutex> lk(mtx_);
+ return size(lk);
+ }
+
+ template <class ValueType, class Queue>
+ void sync_queue_base<ValueType, Queue>::throw_if_closed(unique_lock<mutex>& lk)
+ {
+ if (closed(lk))
+ {
+ BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
+ }
+ }
+ template <class ValueType, class Queue>
+ void sync_queue_base<ValueType, Queue>::throw_if_closed(lock_guard<mutex>& lk)
+ {
+ if (closed(lk))
+ {
+ BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
+ }
+ }
+
+ template <class ValueType, class Queue>
+ void sync_queue_base<ValueType, Queue>::wait_until_not_empty(unique_lock<mutex>& lk)
+ {
+ for (;;)
+ {
+ if (! empty(lk)) break;
+ throw_if_closed(lk);
+ not_empty_.wait(lk);
+ }
+ }
+ template <class ValueType, class Queue>
+ bool sync_queue_base<ValueType, Queue>::wait_until_not_empty_or_closed(unique_lock<mutex>& lk)
+ {
+ for (;;)
+ {
+ if (! empty(lk)) break;
+ if (closed(lk)) return true;
+ not_empty_.wait(lk);
+ }
+ return false;
+ }
+
+ template <class ValueType, class Queue>
+ queue_op_status sync_queue_base<ValueType, Queue>::wait_until_not_empty_until(unique_lock<mutex>& lk, time_point const&tp)
+ {
+ for (;;)
+ {
+ if (! empty(lk)) return queue_op_status::success;
+ throw_if_closed(lk);
+ if (not_empty_.wait_until(lk, tp) == cv_status::timeout ) return queue_op_status::timeout;
+ }
+ }
+
+
+} // detail
+} // concurrent
+} // boost
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/queue_adaptor.hpp b/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/queue_adaptor.hpp
new file mode 100644
index 00000000000..f04e0354f75
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/queue_adaptor.hpp
@@ -0,0 +1,209 @@
+#ifndef BOOST_THREAD_QUEUE_ADAPTOR_HPP
+#define BOOST_THREAD_QUEUE_ADAPTOR_HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2014. Distributed under the 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 http://www.boost.org/libs/thread for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/concurrent_queues/queue_op_status.hpp>
+#include <boost/thread/concurrent_queues/queue_base.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+namespace concurrent
+{
+namespace detail
+{
+
+ template <typename Queue>
+ class queue_adaptor_copyable_only :
+ public boost::queue_base<typename Queue::value_type, typename Queue::size_type>
+ {
+ Queue queue;
+ public:
+ typedef typename Queue::value_type value_type;
+ typedef typename Queue::size_type size_type;
+
+ // Constructors/Assignment/Destructors
+ queue_adaptor_copyable_only() {}
+
+ // Observers
+ bool empty() const { return queue.empty(); }
+ bool full() const { return queue.full(); }
+ size_type size() const { return queue.size(); }
+ bool closed() const { return queue.closed(); }
+
+ // Modifiers
+ void close() { queue.close(); }
+
+ void push(const value_type& x) { queue.push(x); }
+
+ void pull(value_type& x) { queue.pull(x); };
+ value_type pull() { return queue.pull(); }
+
+ queue_op_status try_push(const value_type& x) { return queue.try_push(x); }
+ queue_op_status try_pull(value_type& x) { return queue.try_pull(x); }
+
+ queue_op_status nonblocking_push(const value_type& x) { return queue.nonblocking_push(x); }
+ queue_op_status nonblocking_pull(value_type& x) { return queue.nonblocking_pull(x); }
+
+ queue_op_status wait_push(const value_type& x) { return queue.wait_push(x); }
+ queue_op_status wait_pull(value_type& x) { return queue.wait_pull(x); }
+
+ };
+ template <typename Queue>
+ class queue_adaptor_movable_only :
+ public boost::queue_base<typename Queue::value_type, typename Queue::size_type>
+ {
+ Queue queue;
+ public:
+ typedef typename Queue::value_type value_type;
+ typedef typename Queue::size_type size_type;
+
+ // Constructors/Assignment/Destructors
+
+ queue_adaptor_movable_only() {}
+
+ // Observers
+ bool empty() const { return queue.empty(); }
+ bool full() const { return queue.full(); }
+ size_type size() const { return queue.size(); }
+ bool closed() const { return queue.closed(); }
+
+ // Modifiers
+ void close() { queue.close(); }
+
+
+ void pull(value_type& x) { queue.pull(x); };
+ // enable_if is_nothrow_copy_movable<value_type>
+ value_type pull() { return queue.pull(); }
+
+ queue_op_status try_pull(value_type& x) { return queue.try_pull(x); }
+
+ queue_op_status nonblocking_pull(value_type& x) { return queue.nonblocking_pull(x); }
+
+ queue_op_status wait_pull(value_type& x) { return queue.wait_pull(x); }
+
+ void push(BOOST_THREAD_RV_REF(value_type) x) { queue.push(boost::move(x)); }
+ queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x) { return queue.try_push(boost::move(x)); }
+ queue_op_status nonblocking_push(BOOST_THREAD_RV_REF(value_type) x) { return queue.nonblocking_push(boost::move(x)); }
+ queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x) { return queue.wait_push(boost::move(x)); }
+ };
+
+ template <typename Queue>
+ class queue_adaptor_copyable_and_movable :
+ public boost::queue_base<typename Queue::value_type, typename Queue::size_type>
+ {
+ Queue queue;
+ public:
+ typedef typename Queue::value_type value_type;
+ typedef typename Queue::size_type size_type;
+
+ // Constructors/Assignment/Destructors
+
+ queue_adaptor_copyable_and_movable() {}
+
+ // Observers
+ bool empty() const { return queue.empty(); }
+ bool full() const { return queue.full(); }
+ size_type size() const { return queue.size(); }
+ bool closed() const { return queue.closed(); }
+
+ // Modifiers
+ void close() { queue.close(); }
+
+
+ void push(const value_type& x) { queue.push(x); }
+
+ void pull(value_type& x) { queue.pull(x); };
+ // enable_if is_nothrow_copy_movable<value_type>
+ value_type pull() { return queue.pull(); }
+
+ queue_op_status try_push(const value_type& x) { return queue.try_push(x); }
+ queue_op_status try_pull(value_type& x) { return queue.try_pull(x); }
+
+ queue_op_status nonblocking_push(const value_type& x) { return queue.nonblocking_push(x); }
+ queue_op_status nonblocking_pull(value_type& x) { return queue.nonblocking_pull(x); }
+
+ queue_op_status wait_push(const value_type& x) { return queue.wait_push(x); }
+ queue_op_status wait_pull(value_type& x) { return queue.wait_pull(x); }
+
+ void push(BOOST_THREAD_RV_REF(value_type) x) { queue.push(boost::move(x)); }
+ queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x) { return queue.try_push(boost::move(x)); }
+ queue_op_status nonblocking_push(BOOST_THREAD_RV_REF(value_type) x) { return queue.nonblocking_push(boost::move(x)); }
+ queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x) { return queue.wait_push(boost::move(x)); }
+ };
+
+
+ template <class Q, class T,
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+#if defined __GNUC__ && ! defined __clang__
+#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5) || !defined(__GXX_EXPERIMENTAL_CXX0X__)
+ bool Copyable = is_copy_constructible<T>::value,
+ bool Movable = true
+#else
+ bool Copyable = std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value,
+ bool Movable = std::is_move_constructible<T>::value && std::is_move_assignable<T>::value
+#endif // __GNUC__
+#elif defined _MSC_VER
+#if _MSC_VER < 1700
+ bool Copyable = is_copy_constructible<T>::value,
+ bool Movable = true
+#else
+ bool Copyable = std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value,
+ bool Movable = std::is_move_constructible<T>::value && std::is_move_assignable<T>::value
+#endif // _MSC_VER
+#else
+ bool Copyable = std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value,
+ bool Movable = std::is_move_constructible<T>::value && std::is_move_assignable<T>::value
+#endif
+#else
+ bool Copyable = is_copy_constructible<T>::value,
+ bool Movable = has_move_emulation_enabled<T>::value
+#endif
+ >
+ struct queue_adaptor;
+
+ template <class Q, class T>
+ struct queue_adaptor<Q, T, true, true> {
+ typedef queue_adaptor_copyable_and_movable<Q> type;
+ };
+ template <class Q, class T>
+ struct queue_adaptor<Q, T, true, false> {
+ typedef queue_adaptor_copyable_only<Q> type;
+ };
+ template <class Q, class T>
+ struct queue_adaptor<Q, T, false, true> {
+ typedef queue_adaptor_movable_only<Q> type;
+ };
+
+}
+
+ template <typename Queue>
+ class queue_adaptor :
+ public detail::queue_adaptor<Queue, typename Queue::value_type>::type
+ {
+ public:
+ typedef typename Queue::value_type value_type;
+ typedef typename Queue::size_type size_type;
+ // Constructors/Assignment/Destructors
+ virtual ~queue_adaptor() {};
+ };
+}
+using concurrent::queue_adaptor;
+
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/queue_base.hpp b/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/queue_base.hpp
new file mode 100755
index 00000000000..0d42839158e
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/queue_base.hpp
@@ -0,0 +1,202 @@
+#ifndef BOOST_THREAD_QUEUE_BASE_HPP
+#define BOOST_THREAD_QUEUE_BASE_HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2014. Distributed under the 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 http://www.boost.org/libs/thread for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/concurrent_queues/queue_op_status.hpp>
+#include <boost/type_traits/conditional.hpp>
+#include <boost/type_traits/is_copy_constructible.hpp>
+
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+namespace concurrent
+{
+namespace detail
+{
+
+ template <typename ValueType, class SizeType>
+ class queue_base_copyable_only
+ {
+ public:
+ typedef ValueType value_type;
+ typedef SizeType size_type;
+
+ // Constructors/Assignment/Destructors
+ virtual ~queue_base_copyable_only() {};
+
+ // Observers
+ virtual bool empty() const = 0;
+ virtual bool full() const = 0;
+ virtual size_type size() const = 0;
+ virtual bool closed() const = 0;
+
+ // Modifiers
+ virtual void close() = 0;
+
+ virtual void push(const value_type& x) = 0;
+
+ virtual void pull(value_type&) = 0;
+ virtual value_type pull() = 0;
+
+ virtual queue_op_status try_push(const value_type& x) = 0;
+ virtual queue_op_status try_pull(value_type&) = 0;
+
+ virtual queue_op_status nonblocking_push(const value_type& x) = 0;
+ virtual queue_op_status nonblocking_pull(value_type&) = 0;
+
+ virtual queue_op_status wait_push(const value_type& x) = 0;
+ virtual queue_op_status wait_pull(ValueType& elem) = 0;
+
+ };
+
+ template <typename ValueType, class SizeType>
+ class queue_base_movable_only
+ {
+ public:
+ typedef ValueType value_type;
+ typedef SizeType size_type;
+ // Constructors/Assignment/Destructors
+ virtual ~queue_base_movable_only() {};
+
+ // Observers
+ virtual bool empty() const = 0;
+ virtual bool full() const = 0;
+ virtual size_type size() const = 0;
+ virtual bool closed() const = 0;
+
+ // Modifiers
+ virtual void close() = 0;
+
+ virtual void pull(value_type&) = 0;
+ // enable_if is_nothrow_movable<value_type>
+ virtual value_type pull() = 0;
+
+ virtual queue_op_status try_pull(value_type&) = 0;
+
+ virtual queue_op_status nonblocking_pull(value_type&) = 0;
+
+ virtual queue_op_status wait_pull(value_type& elem) = 0;
+
+ virtual void push(BOOST_THREAD_RV_REF(value_type) x) = 0;
+ virtual queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x) = 0;
+ virtual queue_op_status nonblocking_push(BOOST_THREAD_RV_REF(value_type) x) = 0;
+ virtual queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x) = 0;
+ };
+
+
+ template <typename ValueType, class SizeType>
+ class queue_base_copyable_and_movable
+ {
+ public:
+ typedef ValueType value_type;
+ typedef SizeType size_type;
+ // Constructors/Assignment/Destructors
+ virtual ~queue_base_copyable_and_movable() {};
+
+
+ // Observers
+ virtual bool empty() const = 0;
+ virtual bool full() const = 0;
+ virtual size_type size() const = 0;
+ virtual bool closed() const = 0;
+
+ // Modifiers
+ virtual void close() = 0;
+
+ virtual void push(const value_type& x) = 0;
+
+ virtual void pull(value_type&) = 0;
+ // enable_if is_nothrow_copy_movable<value_type>
+ virtual value_type pull() = 0;
+
+ virtual queue_op_status try_push(const value_type& x) = 0;
+ virtual queue_op_status try_pull(value_type&) = 0;
+
+ virtual queue_op_status nonblocking_push(const value_type& x) = 0;
+ virtual queue_op_status nonblocking_pull(value_type&) = 0;
+
+ virtual queue_op_status wait_push(const value_type& x) = 0;
+ virtual queue_op_status wait_pull(value_type& elem) = 0;
+
+ virtual void push(BOOST_THREAD_RV_REF(value_type) x) = 0;
+ virtual queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x) = 0;
+ virtual queue_op_status nonblocking_push(BOOST_THREAD_RV_REF(value_type) x) = 0;
+ virtual queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x) = 0;
+ };
+
+ template <class T, class ST,
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+#if defined __GNUC__ && ! defined __clang__
+#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5) || !defined(__GXX_EXPERIMENTAL_CXX0X__)
+ bool Copyable = is_copy_constructible<T>::value,
+ bool Movable = true
+#else
+ bool Copyable = std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value,
+ bool Movable = std::is_move_constructible<T>::value && std::is_move_assignable<T>::value
+#endif // __GNUC__
+#elif defined _MSC_VER
+#if _MSC_VER < 1700
+ bool Copyable = is_copy_constructible<T>::value,
+ bool Movable = true
+#else
+ bool Copyable = std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value,
+ bool Movable = std::is_move_constructible<T>::value && std::is_move_assignable<T>::value
+#endif // _MSC_VER
+#else
+ bool Copyable = std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value,
+ bool Movable = std::is_move_constructible<T>::value && std::is_move_assignable<T>::value
+#endif
+#else
+ bool Copyable = is_copy_constructible<T>::value,
+ bool Movable = has_move_emulation_enabled<T>::value
+#endif
+ >
+ struct queue_base;
+
+ template <class T, class ST>
+ struct queue_base<T, ST, true, true> {
+ typedef queue_base_copyable_and_movable<T, ST> type;
+ };
+ template <class T, class ST>
+ struct queue_base<T, ST, true, false> {
+ typedef queue_base_copyable_only<T, ST> type;
+ };
+ template <class T, class ST>
+ struct queue_base<T, ST, false, true> {
+ typedef queue_base_movable_only<T, ST> type;
+ };
+
+}
+
+ template <typename ValueType, class SizeType=std::size_t>
+ class queue_base :
+ public detail::queue_base<ValueType, SizeType>::type
+ {
+ public:
+ typedef ValueType value_type;
+ typedef SizeType size_type;
+ // Constructors/Assignment/Destructors
+ virtual ~queue_base() {};
+ };
+
+}
+using concurrent::queue_base;
+
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/queue_op_status.hpp b/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/queue_op_status.hpp
new file mode 100644
index 00000000000..197650d0521
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/queue_op_status.hpp
@@ -0,0 +1,46 @@
+#ifndef BOOST_THREAD_QUEUE_OP_STATUS_HPP
+#define BOOST_THREAD_QUEUE_OP_STATUS_HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2014. Distributed under the 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 http://www.boost.org/libs/thread for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/detail/move.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+namespace concurrent
+{
+
+ BOOST_SCOPED_ENUM_DECLARE_BEGIN(queue_op_status)
+ { success = 0, empty, full, closed, busy, timeout, not_ready }
+ BOOST_SCOPED_ENUM_DECLARE_END(queue_op_status)
+
+ struct sync_queue_is_closed : std::exception
+ {
+ };
+
+}
+
+#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
+ struct no_block_tag{};
+ BOOST_CONSTEXPR_OR_CONST no_block_tag no_block = {};
+#endif
+
+ using concurrent::queue_op_status;
+ using concurrent::sync_queue_is_closed;
+
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/queue_views.hpp b/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/queue_views.hpp
new file mode 100644
index 00000000000..5a4512dd6ed
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/queue_views.hpp
@@ -0,0 +1,155 @@
+#ifndef BOOST_THREAD_QUEUE_VIEWS_HPP
+#define BOOST_THREAD_QUEUE_VIEWS_HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2014. Distributed under the 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 http://www.boost.org/libs/thread for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/concurrent_queues/queue_op_status.hpp>
+#include <boost/thread/concurrent_queues/queue_base.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+namespace concurrent
+{
+
+ template <typename Queue>
+ class queue_back_view
+ {
+ Queue* queue;
+ public:
+ typedef typename Queue::value_type value_type;
+ typedef typename Queue::size_type size_type;
+
+ // Constructors/Assignment/Destructors
+ queue_back_view(Queue& q) BOOST_NOEXCEPT : queue(&q) {}
+
+ // Observers
+ bool empty() const { return queue->empty(); }
+ bool full() const { return queue->full(); }
+ size_type size() const { return queue->size(); }
+ bool closed() const { return queue->closed(); }
+
+ // Modifiers
+ void close() { queue->close(); }
+
+ void push(const value_type& x) { queue->push(x); }
+
+ queue_op_status try_push(const value_type& x) { return queue->try_push(x); }
+
+ queue_op_status nonblocking_push(const value_type& x) { return queue->nonblocking_push(x); }
+ queue_op_status wait_push(const value_type& x) { return queue->wait_push(x); }
+
+ void push(BOOST_THREAD_RV_REF(value_type) x) { queue->push(boost::move(x)); }
+ queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->try_push(boost::move(x)); }
+ queue_op_status nonblocking_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->nonblocking_push(boost::move(x)); }
+ queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->wait_push(boost::move(x)); }
+ };
+
+ template <typename Queue>
+ class queue_front_view
+ {
+ Queue* queue;
+ public:
+ typedef typename Queue::value_type value_type;
+ typedef typename Queue::size_type size_type;
+
+ // Constructors/Assignment/Destructors
+ queue_front_view(Queue& q) BOOST_NOEXCEPT : queue(&q) {}
+
+ // Observers
+ bool empty() const { return queue->empty(); }
+ bool full() const { return queue->full(); }
+ size_type size() const { return queue->size(); }
+ bool closed() const { return queue->closed(); }
+
+ // Modifiers
+ void close() { queue->close(); }
+
+ void push(const value_type& x) { queue->push_front(x); }
+
+ void pull(value_type& x) { queue->pull(x); };
+ // enable_if is_nothrow_copy_movable<value_type>
+ value_type pull() { return queue->pull(); }
+
+ queue_op_status try_push(const value_type& x) { return queue->try_push_front(x); }
+
+ queue_op_status try_pull(value_type& x) { return queue->try_pull(x); }
+
+ queue_op_status nonblocking_push(const value_type& x) { return queue->nonblocking_push_front(x); }
+
+ queue_op_status nonblocking_pull(value_type& x) { return queue->nonblocking_pull(x); }
+
+ queue_op_status wait_push(const value_type& x) { return queue->wait_push_front(x); }
+ queue_op_status wait_pull(value_type& x) { return queue->wait_pull(x); }
+ void push(BOOST_THREAD_RV_REF(value_type) x) { queue->push_front(forward<value_type>(x)); }
+ queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->try_push_front(forward<value_type>(x)); }
+ queue_op_status nonblocking_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->nonblocking_push_front(forward<value_type>(x)); }
+ queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->wait_push_front(forward<value_type>(x)); }
+
+ };
+
+#if ! defined BOOST_NO_CXX11_TEMPLATE_ALIASES
+
+ template <class T>
+ using queue_back = queue_back_view<queue_base<T> > ;
+ template <class T>
+ using queue_front = queue_front_view<queue_base<T> > ;
+
+#else
+
+ template <class T>
+ struct queue_back : queue_back_view<queue_base<T> >
+ {
+ typedef queue_back_view<queue_base<T> > base_type;
+ queue_back(queue_base<T>& q) BOOST_NOEXCEPT : base_type(q) {}
+ };
+ template <class T>
+ struct queue_front : queue_front_view<queue_base<T> >
+ {
+ typedef queue_front_view<queue_base<T> > base_type;
+ queue_front(queue_base<T>& q) BOOST_NOEXCEPT : base_type(q) {}
+
+ };
+
+#endif
+
+// template <class Queue>
+// queue_back_view<Queue> back(Queue & q) { return queue_back_view<Queue>(q); }
+// template <class Queue>
+// queue_front_view<Queue> front(Queue & q) { return queue_front_view<Queue>(q); }
+//#if 0
+// template <class T>
+// queue_back<T> back(queue_base<T> & q) { return queue_back<T>(q); }
+// template <class T>
+// queue_front<T> front(queue_base<T> & q) { return queue_front<T>(q); }
+//#else
+// template <class T>
+// typename queue_back<T>::type back(queue_base<T> & q) { return typename queue_back<T>::type(q); }
+// template <class T>
+// typename queue_front<T>::type front(queue_base<T> & q) { return typename queue_front<T>::type(q); }
+//#endif
+}
+
+using concurrent::queue_back_view;
+using concurrent::queue_front_view;
+using concurrent::queue_back;
+using concurrent::queue_front;
+//using concurrent::back;
+//using concurrent::front;
+
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/sync_bounded_queue.hpp b/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/sync_bounded_queue.hpp
new file mode 100644
index 00000000000..e34fa56f37f
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/sync_bounded_queue.hpp
@@ -0,0 +1,725 @@
+#ifndef BOOST_THREAD_CONCURRENT_QUEUES_SYNC_BOUNDED_QUEUE_HPP
+#define BOOST_THREAD_CONCURRENT_QUEUES_SYNC_BOUNDED_QUEUE_HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2013-2014. Distributed under the 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 http://www.boost.org/libs/thread for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/thread/concurrent_queues/queue_op_status.hpp>
+
+#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
+#include <boost/smart_ptr/shared_ptr.hpp>
+#include <boost/smart_ptr/make_shared.hpp>
+#endif
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+namespace concurrent
+{
+ template <typename ValueType>
+ class sync_bounded_queue
+ {
+ public:
+ typedef ValueType value_type;
+ typedef std::size_t size_type;
+
+ // Constructors/Assignment/Destructors
+ BOOST_THREAD_NO_COPYABLE(sync_bounded_queue)
+ explicit sync_bounded_queue(size_type max_elems);
+ template <typename Range>
+ sync_bounded_queue(size_type max_elems, Range range);
+ ~sync_bounded_queue();
+
+ // Observers
+ inline bool empty() const;
+ inline bool full() const;
+ inline size_type capacity() const;
+ inline size_type size() const;
+ inline bool closed() const;
+
+ // Modifiers
+ inline void close();
+
+#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
+ inline void push(const value_type& x);
+ inline void push(BOOST_THREAD_RV_REF(value_type) x);
+ inline bool try_push(const value_type& x);
+ inline bool try_push(BOOST_THREAD_RV_REF(value_type) x);
+ inline bool try_push(no_block_tag, const value_type& x);
+ inline bool try_push(no_block_tag, BOOST_THREAD_RV_REF(value_type) x);
+#endif
+ inline void push_back(const value_type& x);
+ inline void push_back(BOOST_THREAD_RV_REF(value_type) x);
+ inline queue_op_status try_push_back(const value_type& x);
+ inline queue_op_status try_push_back(BOOST_THREAD_RV_REF(value_type) x);
+ inline queue_op_status nonblocking_push_back(const value_type& x);
+ inline queue_op_status nonblocking_push_back(BOOST_THREAD_RV_REF(value_type) x);
+ inline queue_op_status wait_push_back(const value_type& x);
+ inline queue_op_status wait_push_back(BOOST_THREAD_RV_REF(value_type) x);
+
+ // Observers/Modifiers
+#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
+ inline void pull(value_type&);
+ // enable_if is_nothrow_copy_movable<value_type>
+ inline value_type pull();
+ inline shared_ptr<ValueType> ptr_pull();
+ inline bool try_pull(value_type&);
+ inline bool try_pull(no_block_tag,value_type&);
+ inline shared_ptr<ValueType> try_pull();
+#endif
+ inline void pull_front(value_type&);
+ // enable_if is_nothrow_copy_movable<value_type>
+ inline value_type pull_front();
+ inline queue_op_status try_pull_front(value_type&);
+ inline queue_op_status nonblocking_pull_front(value_type&);
+
+ inline queue_op_status wait_pull_front(ValueType& elem);
+
+ private:
+ mutable mutex mtx_;
+ condition_variable not_empty_;
+ condition_variable not_full_;
+ size_type waiting_full_;
+ size_type waiting_empty_;
+ value_type* data_;
+ size_type in_;
+ size_type out_;
+ size_type capacity_;
+ bool closed_;
+
+ inline size_type inc(size_type idx) const BOOST_NOEXCEPT
+ {
+ return (idx + 1) % capacity_;
+ }
+
+ inline bool empty(unique_lock<mutex>& ) const BOOST_NOEXCEPT
+ {
+ return in_ == out_;
+ }
+ inline bool empty(lock_guard<mutex>& ) const BOOST_NOEXCEPT
+ {
+ return in_ == out_;
+ }
+ inline bool full(unique_lock<mutex>& ) const BOOST_NOEXCEPT
+ {
+ return (inc(in_) == out_);
+ }
+ inline bool full(lock_guard<mutex>& ) const BOOST_NOEXCEPT
+ {
+ return (inc(in_) == out_);
+ }
+ inline size_type capacity(lock_guard<mutex>& ) const BOOST_NOEXCEPT
+ {
+ return capacity_-1;
+ }
+ inline size_type size(lock_guard<mutex>& lk) const BOOST_NOEXCEPT
+ {
+ if (full(lk)) return capacity(lk);
+ return ((out_+capacity(lk)-in_) % capacity(lk));
+ }
+
+ inline void throw_if_closed(unique_lock<mutex>&);
+ inline bool closed(unique_lock<mutex>&) const;
+
+#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
+ inline bool try_pull(value_type& x, unique_lock<mutex>& lk);
+ inline shared_ptr<value_type> try_pull(unique_lock<mutex>& lk);
+ inline bool try_push(const value_type& x, unique_lock<mutex>& lk);
+ inline bool try_push(BOOST_THREAD_RV_REF(value_type) x, unique_lock<mutex>& lk);
+#endif
+ inline queue_op_status try_pull_front(value_type& x, unique_lock<mutex>& lk);
+ inline queue_op_status try_push_back(const value_type& x, unique_lock<mutex>& lk);
+ inline queue_op_status try_push_back(BOOST_THREAD_RV_REF(value_type) x, unique_lock<mutex>& lk);
+
+ inline queue_op_status wait_pull_front(value_type& x, unique_lock<mutex>& lk);
+ inline queue_op_status wait_push_back(const value_type& x, unique_lock<mutex>& lk);
+ inline queue_op_status wait_push_back(BOOST_THREAD_RV_REF(value_type) x, unique_lock<mutex>& lk);
+
+ inline void wait_until_not_empty(unique_lock<mutex>& lk);
+ inline void wait_until_not_empty(unique_lock<mutex>& lk, bool&);
+ inline size_type wait_until_not_full(unique_lock<mutex>& lk);
+ inline size_type wait_until_not_full(unique_lock<mutex>& lk, bool&);
+
+
+ inline void notify_not_empty_if_needed(unique_lock<mutex>& lk)
+ {
+ if (waiting_empty_ > 0)
+ {
+ --waiting_empty_;
+ lk.unlock();
+ not_empty_.notify_one();
+ }
+ }
+ inline void notify_not_full_if_needed(unique_lock<mutex>& lk)
+ {
+ if (waiting_full_ > 0)
+ {
+ --waiting_full_;
+ lk.unlock();
+ not_full_.notify_one();
+ }
+ }
+
+#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
+ inline void pull(value_type& elem, unique_lock<mutex>& lk)
+ {
+ elem = boost::move(data_[out_]);
+ out_ = inc(out_);
+ notify_not_full_if_needed(lk);
+ }
+ inline value_type pull(unique_lock<mutex>& lk)
+ {
+ value_type elem = boost::move(data_[out_]);
+ out_ = inc(out_);
+ notify_not_full_if_needed(lk);
+ return boost::move(elem);
+ }
+ inline boost::shared_ptr<value_type> ptr_pull(unique_lock<mutex>& lk)
+ {
+ shared_ptr<value_type> res = make_shared<value_type>(boost::move(data_[out_]));
+ out_ = inc(out_);
+ notify_not_full_if_needed(lk);
+ return res;
+ }
+#endif
+ inline void pull_front(value_type& elem, unique_lock<mutex>& lk)
+ {
+ elem = boost::move(data_[out_]);
+ out_ = inc(out_);
+ notify_not_full_if_needed(lk);
+ }
+ inline value_type pull_front(unique_lock<mutex>& lk)
+ {
+ value_type elem = boost::move(data_[out_]);
+ out_ = inc(out_);
+ notify_not_full_if_needed(lk);
+ return boost::move(elem);
+ }
+
+ inline void set_in(size_type in, unique_lock<mutex>& lk)
+ {
+ in_ = in;
+ notify_not_empty_if_needed(lk);
+ }
+
+ inline void push_at(const value_type& elem, size_type in_p_1, unique_lock<mutex>& lk)
+ {
+ data_[in_] = elem;
+ set_in(in_p_1, lk);
+ }
+
+ inline void push_at(BOOST_THREAD_RV_REF(value_type) elem, size_type in_p_1, unique_lock<mutex>& lk)
+ {
+ data_[in_] = boost::move(elem);
+ set_in(in_p_1, lk);
+ }
+ };
+
+ template <typename ValueType>
+ sync_bounded_queue<ValueType>::sync_bounded_queue(typename sync_bounded_queue<ValueType>::size_type max_elems) :
+ waiting_full_(0), waiting_empty_(0), data_(new value_type[max_elems + 1]), in_(0), out_(0), capacity_(max_elems + 1),
+ closed_(false)
+ {
+ BOOST_ASSERT_MSG(max_elems >= 1, "number of elements must be > 1");
+ }
+
+// template <typename ValueType>
+// template <typename Range>
+// sync_bounded_queue<ValueType>::sync_bounded_queue(size_type max_elems, Range range) :
+// waiting_full_(0), waiting_empty_(0), data_(new value_type[max_elems + 1]), in_(0), out_(0), capacity_(max_elems + 1),
+// closed_(false)
+// {
+// BOOST_ASSERT_MSG(max_elems >= 1, "number of elements must be > 1");
+// BOOST_ASSERT_MSG(max_elems == size(range), "number of elements must match range's size");
+// try
+// {
+// typedef typename Range::iterator iterator_t;
+// iterator_t first = boost::begin(range);
+// iterator_t end = boost::end(range);
+// size_type in = 0;
+// for (iterator_t cur = first; cur != end; ++cur, ++in)
+// {
+// data_[in] = *cur;
+// }
+// set_in(in);
+// }
+// catch (...)
+// {
+// delete[] data_;
+// }
+// }
+
+ template <typename ValueType>
+ sync_bounded_queue<ValueType>::~sync_bounded_queue()
+ {
+ delete[] data_;
+ }
+
+ template <typename ValueType>
+ void sync_bounded_queue<ValueType>::close()
+ {
+ {
+ lock_guard<mutex> lk(mtx_);
+ closed_ = true;
+ }
+ not_empty_.notify_all();
+ not_full_.notify_all();
+ }
+
+ template <typename ValueType>
+ bool sync_bounded_queue<ValueType>::closed() const
+ {
+ lock_guard<mutex> lk(mtx_);
+ return closed_;
+ }
+ template <typename ValueType>
+ bool sync_bounded_queue<ValueType>::closed(unique_lock<mutex>& ) const
+ {
+ return closed_;
+ }
+
+ template <typename ValueType>
+ bool sync_bounded_queue<ValueType>::empty() const
+ {
+ lock_guard<mutex> lk(mtx_);
+ return empty(lk);
+ }
+ template <typename ValueType>
+ bool sync_bounded_queue<ValueType>::full() const
+ {
+ lock_guard<mutex> lk(mtx_);
+ return full(lk);
+ }
+
+ template <typename ValueType>
+ typename sync_bounded_queue<ValueType>::size_type sync_bounded_queue<ValueType>::capacity() const
+ {
+ lock_guard<mutex> lk(mtx_);
+ return capacity(lk);
+ }
+
+ template <typename ValueType>
+ typename sync_bounded_queue<ValueType>::size_type sync_bounded_queue<ValueType>::size() const
+ {
+ lock_guard<mutex> lk(mtx_);
+ return size(lk);
+ }
+
+#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
+ template <typename ValueType>
+ bool sync_bounded_queue<ValueType>::try_pull(ValueType& elem, unique_lock<mutex>& lk)
+ {
+ if (empty(lk))
+ {
+ throw_if_closed(lk);
+ return false;
+ }
+ pull(elem, lk);
+ return true;
+ }
+ template <typename ValueType>
+ shared_ptr<ValueType> sync_bounded_queue<ValueType>::try_pull(unique_lock<mutex>& lk)
+ {
+ if (empty(lk))
+ {
+ throw_if_closed(lk);
+ return shared_ptr<ValueType>();
+ }
+ return ptr_pull(lk);
+ }
+ template <typename ValueType>
+ bool sync_bounded_queue<ValueType>::try_pull(ValueType& elem)
+ {
+ unique_lock<mutex> lk(mtx_);
+ return try_pull(elem, lk);
+ }
+#endif
+
+ template <typename ValueType>
+ queue_op_status sync_bounded_queue<ValueType>::try_pull_front(ValueType& elem, unique_lock<mutex>& lk)
+ {
+ if (empty(lk))
+ {
+ if (closed(lk)) return queue_op_status::closed;
+ return queue_op_status::empty;
+ }
+ pull_front(elem, lk);
+ return queue_op_status::success;
+ }
+
+ template <typename ValueType>
+ queue_op_status sync_bounded_queue<ValueType>::try_pull_front(ValueType& elem)
+ {
+ unique_lock<mutex> lk(mtx_);
+ return try_pull_front(elem, lk);
+ }
+
+#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
+ template <typename ValueType>
+ bool sync_bounded_queue<ValueType>::try_pull(no_block_tag,ValueType& elem)
+ {
+ unique_lock<mutex> lk(mtx_, try_to_lock);
+ if (!lk.owns_lock())
+ {
+ return false;
+ }
+ return try_pull(elem, lk);
+ }
+ template <typename ValueType>
+ boost::shared_ptr<ValueType> sync_bounded_queue<ValueType>::try_pull()
+ {
+ unique_lock<mutex> lk(mtx_);
+ return try_pull(lk);
+ }
+#endif
+
+ template <typename ValueType>
+ queue_op_status sync_bounded_queue<ValueType>::nonblocking_pull_front(ValueType& elem)
+ {
+ unique_lock<mutex> lk(mtx_, try_to_lock);
+ if (!lk.owns_lock())
+ {
+ return queue_op_status::busy;
+ }
+ return try_pull_front(elem, lk);
+ }
+
+ template <typename ValueType>
+ void sync_bounded_queue<ValueType>::throw_if_closed(unique_lock<mutex>&)
+ {
+ if (closed_)
+ {
+ BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
+ }
+ }
+
+ template <typename ValueType>
+ void sync_bounded_queue<ValueType>::wait_until_not_empty(unique_lock<mutex>& lk)
+ {
+ for (;;)
+ {
+ if (out_ != in_) break;
+ throw_if_closed(lk);
+ ++waiting_empty_;
+ not_empty_.wait(lk);
+ }
+ }
+ template <typename ValueType>
+ void sync_bounded_queue<ValueType>::wait_until_not_empty(unique_lock<mutex>& lk, bool & closed)
+ {
+ for (;;)
+ {
+ if (out_ != in_) break;
+ if (closed_) {closed=true; return;}
+ ++waiting_empty_;
+ not_empty_.wait(lk);
+ }
+ }
+
+#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
+ template <typename ValueType>
+ void sync_bounded_queue<ValueType>::pull(ValueType& elem)
+ {
+ unique_lock<mutex> lk(mtx_);
+ wait_until_not_empty(lk);
+ pull(elem, lk);
+ }
+// template <typename ValueType>
+// void sync_bounded_queue<ValueType>::pull(ValueType& elem, bool & closed)
+// {
+// unique_lock<mutex> lk(mtx_);
+// wait_until_not_empty(lk, closed);
+// if (closed) {return;}
+// pull(elem, lk);
+// }
+
+ // enable if ValueType is nothrow movable
+ template <typename ValueType>
+ ValueType sync_bounded_queue<ValueType>::pull()
+ {
+ unique_lock<mutex> lk(mtx_);
+ wait_until_not_empty(lk);
+ return pull(lk);
+ }
+ template <typename ValueType>
+ boost::shared_ptr<ValueType> sync_bounded_queue<ValueType>::ptr_pull()
+ {
+ unique_lock<mutex> lk(mtx_);
+ wait_until_not_empty(lk);
+ return ptr_pull(lk);
+ }
+
+#endif
+
+ template <typename ValueType>
+ void sync_bounded_queue<ValueType>::pull_front(ValueType& elem)
+ {
+ unique_lock<mutex> lk(mtx_);
+ wait_until_not_empty(lk);
+ pull_front(elem, lk);
+ }
+
+ // enable if ValueType is nothrow movable
+ template <typename ValueType>
+ ValueType sync_bounded_queue<ValueType>::pull_front()
+ {
+ unique_lock<mutex> lk(mtx_);
+ wait_until_not_empty(lk);
+ return pull_front(lk);
+ }
+
+ template <typename ValueType>
+ queue_op_status sync_bounded_queue<ValueType>::wait_pull_front(ValueType& elem, unique_lock<mutex>& lk)
+ {
+ if (empty(lk) && closed(lk)) {return queue_op_status::closed;}
+ wait_until_not_empty(lk);
+ pull_front(elem, lk);
+ return queue_op_status::success;
+ }
+ template <typename ValueType>
+ queue_op_status sync_bounded_queue<ValueType>::wait_pull_front(ValueType& elem)
+ {
+ unique_lock<mutex> lk(mtx_);
+ return wait_pull_front(elem, lk);
+ }
+
+#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
+ template <typename ValueType>
+ bool sync_bounded_queue<ValueType>::try_push(const ValueType& elem, unique_lock<mutex>& lk)
+ {
+ throw_if_closed(lk);
+ size_type in_p_1 = inc(in_);
+ if (in_p_1 == out_) // full()
+ {
+ return false;
+ }
+ push_at(elem, in_p_1, lk);
+ return true;
+ }
+ template <typename ValueType>
+ bool sync_bounded_queue<ValueType>::try_push(const ValueType& elem)
+ {
+ unique_lock<mutex> lk(mtx_);
+ return try_push(elem, lk);
+ }
+
+#endif
+
+ template <typename ValueType>
+ queue_op_status sync_bounded_queue<ValueType>::try_push_back(const ValueType& elem, unique_lock<mutex>& lk)
+ {
+ if (closed(lk)) return queue_op_status::closed;
+ size_type in_p_1 = inc(in_);
+ if (in_p_1 == out_) // full()
+ {
+ return queue_op_status::full;
+ }
+ push_at(elem, in_p_1, lk);
+ return queue_op_status::success;
+ }
+
+ template <typename ValueType>
+ queue_op_status sync_bounded_queue<ValueType>::try_push_back(const ValueType& elem)
+ {
+ unique_lock<mutex> lk(mtx_);
+ return try_push_back(elem, lk);
+ }
+
+ template <typename ValueType>
+ queue_op_status sync_bounded_queue<ValueType>::wait_push_back(const ValueType& elem, unique_lock<mutex>& lk)
+ {
+ if (closed(lk)) return queue_op_status::closed;
+ push_at(elem, wait_until_not_full(lk), lk);
+ return queue_op_status::success;
+ }
+ template <typename ValueType>
+ queue_op_status sync_bounded_queue<ValueType>::wait_push_back(const ValueType& elem)
+ {
+ unique_lock<mutex> lk(mtx_);
+ return wait_push_back(elem, lk);
+ }
+
+
+#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
+ template <typename ValueType>
+ bool sync_bounded_queue<ValueType>::try_push(no_block_tag, const ValueType& elem)
+ {
+ unique_lock<mutex> lk(mtx_, try_to_lock);
+ if (!lk.owns_lock()) return false;
+ return try_push(elem, lk);
+ }
+#endif
+
+ template <typename ValueType>
+ queue_op_status sync_bounded_queue<ValueType>::nonblocking_push_back(const ValueType& elem)
+ {
+ unique_lock<mutex> lk(mtx_, try_to_lock);
+ if (!lk.owns_lock()) return queue_op_status::busy;
+ return try_push_back(elem, lk);
+ }
+
+ template <typename ValueType>
+ typename sync_bounded_queue<ValueType>::size_type sync_bounded_queue<ValueType>::wait_until_not_full(unique_lock<mutex>& lk)
+ {
+ for (;;)
+ {
+ throw_if_closed(lk);
+ size_type in_p_1 = inc(in_);
+ if (in_p_1 != out_) // ! full()
+ {
+ return in_p_1;
+ }
+ ++waiting_full_;
+ not_full_.wait(lk);
+ }
+ }
+
+#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
+ template <typename ValueType>
+ void sync_bounded_queue<ValueType>::push(const ValueType& elem)
+ {
+ unique_lock<mutex> lk(mtx_);
+ push_at(elem, wait_until_not_full(lk), lk);
+ }
+#endif
+ template <typename ValueType>
+ void sync_bounded_queue<ValueType>::push_back(const ValueType& elem)
+ {
+ unique_lock<mutex> lk(mtx_);
+ push_at(elem, wait_until_not_full(lk), lk);
+ }
+
+#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
+ template <typename ValueType>
+ bool sync_bounded_queue<ValueType>::try_push(BOOST_THREAD_RV_REF(ValueType) elem, unique_lock<mutex>& lk)
+ {
+ throw_if_closed(lk);
+ size_type in_p_1 = inc(in_);
+ if (in_p_1 == out_) // full()
+ {
+ return false;
+ }
+ push_at(boost::move(elem), in_p_1, lk);
+ return true;
+ }
+
+ template <typename ValueType>
+ bool sync_bounded_queue<ValueType>::try_push(BOOST_THREAD_RV_REF(ValueType) elem)
+ {
+ unique_lock<mutex> lk(mtx_);
+ return try_push(boost::move(elem), lk);
+ }
+#endif
+
+ template <typename ValueType>
+ queue_op_status sync_bounded_queue<ValueType>::try_push_back(BOOST_THREAD_RV_REF(ValueType) elem, unique_lock<mutex>& lk)
+ {
+ if (closed(lk)) return queue_op_status::closed;
+ size_type in_p_1 = inc(in_);
+ if (in_p_1 == out_) // full()
+ {
+ return queue_op_status::full;
+ }
+ push_at(boost::move(elem), in_p_1, lk);
+ return queue_op_status::success;
+ }
+ template <typename ValueType>
+ queue_op_status sync_bounded_queue<ValueType>::try_push_back(BOOST_THREAD_RV_REF(ValueType) elem)
+ {
+ unique_lock<mutex> lk(mtx_);
+ return try_push_back(boost::move(elem), lk);
+ }
+
+ template <typename ValueType>
+ queue_op_status sync_bounded_queue<ValueType>::wait_push_back(BOOST_THREAD_RV_REF(ValueType) elem, unique_lock<mutex>& lk)
+ {
+ if (closed(lk)) return queue_op_status::closed;
+ push_at(boost::move(elem), wait_until_not_full(lk), lk);
+ return queue_op_status::success;
+ }
+ template <typename ValueType>
+ queue_op_status sync_bounded_queue<ValueType>::wait_push_back(BOOST_THREAD_RV_REF(ValueType) elem)
+ {
+ unique_lock<mutex> lk(mtx_);
+ return try_push_back(boost::move(elem), lk);
+ }
+
+
+#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
+ template <typename ValueType>
+ bool sync_bounded_queue<ValueType>::try_push(no_block_tag, BOOST_THREAD_RV_REF(ValueType) elem)
+ {
+ unique_lock<mutex> lk(mtx_, try_to_lock);
+ if (!lk.owns_lock())
+ {
+ return false;
+ }
+ return try_push(boost::move(elem), lk);
+ }
+#endif
+ template <typename ValueType>
+ queue_op_status sync_bounded_queue<ValueType>::nonblocking_push_back(BOOST_THREAD_RV_REF(ValueType) elem)
+ {
+ unique_lock<mutex> lk(mtx_, try_to_lock);
+ if (!lk.owns_lock())
+ {
+ return queue_op_status::busy;
+ }
+ return try_push_back(boost::move(elem), lk);
+ }
+
+#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
+ template <typename ValueType>
+ void sync_bounded_queue<ValueType>::push(BOOST_THREAD_RV_REF(ValueType) elem)
+ {
+ unique_lock<mutex> lk(mtx_);
+ push_at(boost::move(elem), wait_until_not_full(lk), lk);
+ }
+#endif
+ template <typename ValueType>
+ void sync_bounded_queue<ValueType>::push_back(BOOST_THREAD_RV_REF(ValueType) elem)
+ {
+ unique_lock<mutex> lk(mtx_);
+ push_at(boost::move(elem), wait_until_not_full(lk), lk);
+ }
+
+ template <typename ValueType>
+ sync_bounded_queue<ValueType>& operator<<(sync_bounded_queue<ValueType>& sbq, BOOST_THREAD_RV_REF(ValueType) elem)
+ {
+ sbq.push_back(boost::move(elem));
+ return sbq;
+ }
+
+ template <typename ValueType>
+ sync_bounded_queue<ValueType>& operator<<(sync_bounded_queue<ValueType>& sbq, ValueType const&elem)
+ {
+ sbq.push_back(elem);
+ return sbq;
+ }
+
+ template <typename ValueType>
+ sync_bounded_queue<ValueType>& operator>>(sync_bounded_queue<ValueType>& sbq, ValueType &elem)
+ {
+ sbq.pull_front(elem);
+ return sbq;
+ }
+}
+using concurrent::sync_bounded_queue;
+
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/sync_deque.hpp b/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/sync_deque.hpp
new file mode 100644
index 00000000000..c84dae022ac
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/sync_deque.hpp
@@ -0,0 +1,327 @@
+#ifndef BOOST_THREAD_CONCURRENT_QUEUES_SYNC_DEQUE_HPP
+#define BOOST_THREAD_CONCURRENT_QUEUES_SYNC_DEQUE_HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2013-2014. Distributed under the 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 http://www.boost.org/libs/thread for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/concurrent_queues/detail/sync_queue_base.hpp>
+#include <boost/thread/concurrent_queues/queue_op_status.hpp>
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/csbl/devector.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/mutex.hpp>
+
+#include <boost/throw_exception.hpp>
+#include <boost/smart_ptr/shared_ptr.hpp>
+#include <boost/smart_ptr/make_shared.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+namespace concurrent
+{
+ template <class ValueType, class Container = csbl::devector<ValueType> >
+ class sync_deque
+ : public detail::sync_queue_base<ValueType, Container >
+ {
+ typedef detail::sync_queue_base<ValueType, Container > super;
+
+ public:
+ typedef ValueType value_type;
+ //typedef typename super::value_type value_type; // fixme
+ typedef typename super::underlying_queue_type underlying_queue_type;
+ typedef typename super::size_type size_type;
+ typedef typename super::op_status op_status;
+
+ // Constructors/Assignment/Destructors
+ BOOST_THREAD_NO_COPYABLE(sync_deque)
+ inline sync_deque();
+ //template <typename Range>
+ //inline explicit sync_deque(Range range);
+ inline ~sync_deque();
+
+ // Modifiers
+ inline void push_back(const value_type& x);
+ inline queue_op_status try_push_back(const value_type& x);
+ inline queue_op_status nonblocking_push_back(const value_type& x);
+ inline queue_op_status wait_push_back(const value_type& x);
+ inline void push_back(BOOST_THREAD_RV_REF(value_type) x);
+ inline queue_op_status try_push_back(BOOST_THREAD_RV_REF(value_type) x);
+ inline queue_op_status nonblocking_push_back(BOOST_THREAD_RV_REF(value_type) x);
+ inline queue_op_status wait_push_back(BOOST_THREAD_RV_REF(value_type) x);
+
+ // Observers/Modifiers
+ inline void pull_front(value_type&);
+ // enable_if is_nothrow_copy_movable<value_type>
+ inline value_type pull_front();
+
+ inline queue_op_status try_pull_front(value_type&);
+ inline queue_op_status nonblocking_pull_front(value_type&);
+ inline queue_op_status wait_pull_front(ValueType& elem);
+
+ private:
+
+ inline queue_op_status try_pull_front(value_type& x, unique_lock<mutex>& lk);
+ inline queue_op_status wait_pull_front(value_type& x, unique_lock<mutex>& lk);
+ inline queue_op_status try_push_back(const value_type& x, unique_lock<mutex>& lk);
+ inline queue_op_status wait_push_back(const value_type& x, unique_lock<mutex>& lk);
+ inline queue_op_status try_push_back(BOOST_THREAD_RV_REF(value_type) x, unique_lock<mutex>& lk);
+ inline queue_op_status wait_push_back(BOOST_THREAD_RV_REF(value_type) x, unique_lock<mutex>& lk);
+
+ inline void pull_front(value_type& elem, unique_lock<mutex>& )
+ {
+ elem = boost::move(super::data_.front());
+ super::data_.pop_front();
+ }
+ inline value_type pull_front(unique_lock<mutex>& )
+ {
+ value_type e = boost::move(super::data_.front());
+ super::data_.pop_front();
+ return boost::move(e);
+ }
+
+ inline void push_back(const value_type& elem, unique_lock<mutex>& lk)
+ {
+ super::data_.push_back(elem);
+ super::notify_not_empty_if_needed(lk);
+ }
+
+ inline void push_back(BOOST_THREAD_RV_REF(value_type) elem, unique_lock<mutex>& lk)
+ {
+ super::data_.push_back(boost::move(elem));
+ super::notify_not_empty_if_needed(lk);
+ }
+ };
+
+ template <class ValueType, class Container>
+ sync_deque<ValueType, Container>::sync_deque() :
+ super()
+ {
+ }
+
+// template <class ValueType, class Container>
+// template <class Range>
+// explicit sync_deque<ValueType, Container>::sync_deque(Range range) :
+// data_(), closed_(false)
+// {
+// try
+// {
+// typedef typename Range::iterator iterator_t;
+// iterator_t first = boost::begin(range);
+// iterator_t end = boost::end(range);
+// for (iterator_t cur = first; cur != end; ++cur)
+// {
+// data_.push(boost::move(*cur));;
+// }
+// notify_not_empty_if_needed(lk);
+// }
+// catch (...)
+// {
+// delete[] data_;
+// }
+// }
+
+ template <class ValueType, class Container>
+ sync_deque<ValueType, Container>::~sync_deque()
+ {
+ }
+
+ template <class ValueType, class Container>
+ queue_op_status sync_deque<ValueType, Container>::try_pull_front(ValueType& elem, unique_lock<mutex>& lk)
+ {
+ if (super::empty(lk))
+ {
+ if (super::closed(lk)) return queue_op_status::closed;
+ return queue_op_status::empty;
+ }
+ pull_front(elem, lk);
+ return queue_op_status::success;
+ }
+ template <class ValueType, class Container>
+ queue_op_status sync_deque<ValueType, Container>::wait_pull_front(ValueType& elem, unique_lock<mutex>& lk)
+ {
+ if (super::empty(lk))
+ {
+ if (super::closed(lk)) return queue_op_status::closed;
+ }
+ bool has_been_closed = super::wait_until_not_empty_or_closed(lk);
+ if (has_been_closed) return queue_op_status::closed;
+ pull_front(elem, lk);
+ return queue_op_status::success;
+ }
+
+ template <class ValueType, class Container>
+ queue_op_status sync_deque<ValueType, Container>::try_pull_front(ValueType& elem)
+ {
+ unique_lock<mutex> lk(super::mtx_);
+ return try_pull_front(elem, lk);
+ }
+
+ template <class ValueType, class Container>
+ queue_op_status sync_deque<ValueType, Container>::wait_pull_front(ValueType& elem)
+ {
+ unique_lock<mutex> lk(super::mtx_);
+ return wait_pull_front(elem, lk);
+ }
+
+ template <class ValueType, class Container>
+ queue_op_status sync_deque<ValueType, Container>::nonblocking_pull_front(ValueType& elem)
+ {
+ unique_lock<mutex> lk(super::mtx_, try_to_lock);
+ if (!lk.owns_lock())
+ {
+ return queue_op_status::busy;
+ }
+ return try_pull_front(elem, lk);
+ }
+
+ template <class ValueType, class Container>
+ void sync_deque<ValueType, Container>::pull_front(ValueType& elem)
+ {
+ unique_lock<mutex> lk(super::mtx_);
+ super::wait_until_not_empty(lk);
+ pull_front(elem, lk);
+ }
+
+ // enable if ValueType is nothrow movable
+ template <class ValueType, class Container>
+ ValueType sync_deque<ValueType, Container>::pull_front()
+ {
+ unique_lock<mutex> lk(super::mtx_);
+ super::wait_until_not_empty(lk);
+ return pull_front(lk);
+ }
+
+ template <class ValueType, class Container>
+ queue_op_status sync_deque<ValueType, Container>::try_push_back(const ValueType& elem, unique_lock<mutex>& lk)
+ {
+ if (super::closed(lk)) return queue_op_status::closed;
+ push_back(elem, lk);
+ return queue_op_status::success;
+ }
+
+ template <class ValueType, class Container>
+ queue_op_status sync_deque<ValueType, Container>::try_push_back(const ValueType& elem)
+ {
+ unique_lock<mutex> lk(super::mtx_);
+ return try_push_back(elem, lk);
+ }
+
+ template <class ValueType, class Container>
+ queue_op_status sync_deque<ValueType, Container>::wait_push_back(const ValueType& elem, unique_lock<mutex>& lk)
+ {
+ if (super::closed(lk)) return queue_op_status::closed;
+ push_back(elem, lk);
+ return queue_op_status::success;
+ }
+
+ template <class ValueType, class Container>
+ queue_op_status sync_deque<ValueType, Container>::wait_push_back(const ValueType& elem)
+ {
+ unique_lock<mutex> lk(super::mtx_);
+ return wait_push_back(elem, lk);
+ }
+
+ template <class ValueType, class Container>
+ queue_op_status sync_deque<ValueType, Container>::nonblocking_push_back(const ValueType& elem)
+ {
+ unique_lock<mutex> lk(super::mtx_, try_to_lock);
+ if (!lk.owns_lock()) return queue_op_status::busy;
+ return try_push_back(elem, lk);
+ }
+
+ template <class ValueType, class Container>
+ void sync_deque<ValueType, Container>::push_back(const ValueType& elem)
+ {
+ unique_lock<mutex> lk(super::mtx_);
+ super::throw_if_closed(lk);
+ push_back(elem, lk);
+ }
+
+ template <class ValueType, class Container>
+ queue_op_status sync_deque<ValueType, Container>::try_push_back(BOOST_THREAD_RV_REF(ValueType) elem, unique_lock<mutex>& lk)
+ {
+ if (super::closed(lk)) return queue_op_status::closed;
+ push_back(boost::move(elem), lk);
+ return queue_op_status::success;
+ }
+
+ template <class ValueType, class Container>
+ queue_op_status sync_deque<ValueType, Container>::try_push_back(BOOST_THREAD_RV_REF(ValueType) elem)
+ {
+ unique_lock<mutex> lk(super::mtx_);
+ return try_push_back(boost::move(elem), lk);
+ }
+
+ template <class ValueType, class Container>
+ queue_op_status sync_deque<ValueType, Container>::wait_push_back(BOOST_THREAD_RV_REF(ValueType) elem, unique_lock<mutex>& lk)
+ {
+ if (super::closed(lk)) return queue_op_status::closed;
+ push_back(boost::move(elem), lk);
+ return queue_op_status::success;
+ }
+
+ template <class ValueType, class Container>
+ queue_op_status sync_deque<ValueType, Container>::wait_push_back(BOOST_THREAD_RV_REF(ValueType) elem)
+ {
+ unique_lock<mutex> lk(super::mtx_);
+ return wait_push_back(boost::move(elem), lk);
+ }
+
+ template <class ValueType, class Container>
+ queue_op_status sync_deque<ValueType, Container>::nonblocking_push_back(BOOST_THREAD_RV_REF(ValueType) elem)
+ {
+ unique_lock<mutex> lk(super::mtx_, try_to_lock);
+ if (!lk.owns_lock())
+ {
+ return queue_op_status::busy;
+ }
+ return try_push_back(boost::move(elem), lk);
+ }
+
+ template <class ValueType, class Container>
+ void sync_deque<ValueType, Container>::push_back(BOOST_THREAD_RV_REF(ValueType) elem)
+ {
+ unique_lock<mutex> lk(super::mtx_);
+ super::throw_if_closed(lk);
+ push_back(boost::move(elem), lk);
+ }
+
+ template <class ValueType, class Container>
+ sync_deque<ValueType, Container>& operator<<(sync_deque<ValueType, Container>& sbq, BOOST_THREAD_RV_REF(ValueType) elem)
+ {
+ sbq.push_back(boost::move(elem));
+ return sbq;
+ }
+
+ template <class ValueType, class Container>
+ sync_deque<ValueType, Container>& operator<<(sync_deque<ValueType, Container>& sbq, ValueType const&elem)
+ {
+ sbq.push_back(elem);
+ return sbq;
+ }
+
+ template <class ValueType, class Container>
+ sync_deque<ValueType, Container>& operator>>(sync_deque<ValueType, Container>& sbq, ValueType &elem)
+ {
+ sbq.pull_front(elem);
+ return sbq;
+ }
+
+}
+using concurrent::sync_deque;
+
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/sync_priority_queue.hpp b/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/sync_priority_queue.hpp
new file mode 100644
index 00000000000..d604faa7423
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/sync_priority_queue.hpp
@@ -0,0 +1,369 @@
+// 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)
+//
+
+#ifndef BOOST_THREAD_SYNC_PRIORITY_QUEUE
+#define BOOST_THREAD_SYNC_PRIORITY_QUEUE
+
+#include <boost/thread/detail/config.hpp>
+
+#include <boost/thread/concurrent_queues/detail/sync_queue_base.hpp>
+#include <boost/thread/concurrent_queues/queue_op_status.hpp>
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/csbl/vector.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/mutex.hpp>
+
+#include <boost/atomic.hpp>
+#include <boost/chrono/duration.hpp>
+#include <boost/chrono/time_point.hpp>
+
+#include <exception>
+#include <queue>
+#include <utility>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+namespace detail {
+
+ template <
+ class Type,
+ class Container = csbl::vector<Type>,
+ class Compare = std::less<Type>
+ >
+ class priority_queue
+ {
+ private:
+ Container _elements;
+ Compare _compare;
+ public:
+ typedef Type value_type;
+ typedef typename Container::size_type size_type;
+
+ explicit priority_queue(const Compare& compare = Compare())
+ : _elements(), _compare(compare)
+ { }
+
+ size_type size() const
+ {
+ return _elements.size();
+ }
+
+ bool empty() const
+ {
+ return _elements.empty();
+ }
+
+ void push(Type const& element)
+ {
+ _elements.push_back(element);
+ std::push_heap(_elements.begin(), _elements.end(), _compare);
+ }
+ void push(BOOST_RV_REF(Type) element)
+ {
+ _elements.push_back(boost::move(element));
+ std::push_heap(_elements.begin(), _elements.end(), _compare);
+ }
+
+ void pop()
+ {
+ std::pop_heap(_elements.begin(), _elements.end(), _compare);
+ _elements.pop_back();
+ }
+ Type pull()
+ {
+ Type result = boost::move(_elements.front());
+ pop();
+ return boost::move(result);
+ }
+
+ Type const& top()
+ {
+ return _elements.front();
+ }
+ };
+}
+
+namespace concurrent
+{
+ template <class ValueType,
+ class Container = csbl::vector<ValueType>,
+ class Compare = std::less<typename Container::value_type> >
+ class sync_priority_queue
+ : public detail::sync_queue_base<ValueType, boost::detail::priority_queue<ValueType,Container,Compare> >
+ {
+ typedef detail::sync_queue_base<ValueType, boost::detail::priority_queue<ValueType,Container,Compare> > super;
+
+ public:
+ typedef ValueType value_type;
+ //typedef typename super::value_type value_type; // fixme
+ typedef typename super::underlying_queue_type underlying_queue_type;
+ typedef typename super::size_type size_type;
+ typedef typename super::op_status op_status;
+
+ typedef chrono::steady_clock clock;
+ protected:
+
+ public:
+ sync_priority_queue() {}
+
+ ~sync_priority_queue()
+ {
+ if(!super::closed())
+ {
+ super::close();
+ }
+ }
+
+ void push(const ValueType& elem);
+ void push(BOOST_THREAD_RV_REF(ValueType) elem);
+
+ queue_op_status try_push(const ValueType& elem);
+ queue_op_status try_push(BOOST_THREAD_RV_REF(ValueType) elem);
+
+ ValueType pull();
+
+ void pull(ValueType&);
+
+ queue_op_status pull_until(const clock::time_point&, ValueType&);
+ queue_op_status pull_for(const clock::duration&, ValueType&);
+
+ queue_op_status try_pull(ValueType& elem);
+ queue_op_status wait_pull(ValueType& elem);
+ queue_op_status nonblocking_pull(ValueType&);
+
+ private:
+ void push(unique_lock<mutex>&, const ValueType& elem);
+ void push(lock_guard<mutex>&, const ValueType& elem);
+ void push(unique_lock<mutex>&, BOOST_THREAD_RV_REF(ValueType) elem);
+ void push(lock_guard<mutex>&, BOOST_THREAD_RV_REF(ValueType) elem);
+
+ queue_op_status try_push(unique_lock<mutex>&, const ValueType& elem);
+ queue_op_status try_push(unique_lock<mutex>&, BOOST_THREAD_RV_REF(ValueType) elem);
+
+ ValueType pull(unique_lock<mutex>&);
+ ValueType pull(lock_guard<mutex>&);
+
+ void pull(unique_lock<mutex>&, ValueType&);
+ void pull(lock_guard<mutex>&, ValueType&);
+
+ queue_op_status try_pull(lock_guard<mutex>& lk, ValueType& elem);
+ queue_op_status try_pull(unique_lock<mutex>& lk, ValueType& elem);
+
+ queue_op_status wait_pull(unique_lock<mutex>& lk, ValueType& elem);
+
+ queue_op_status nonblocking_pull(unique_lock<mutex>& lk, ValueType&);
+
+ sync_priority_queue(const sync_priority_queue&);
+ sync_priority_queue& operator= (const sync_priority_queue&);
+ sync_priority_queue(BOOST_THREAD_RV_REF(sync_priority_queue));
+ sync_priority_queue& operator= (BOOST_THREAD_RV_REF(sync_priority_queue));
+ }; //end class
+
+
+ //////////////////////
+ template <class T, class Container,class Cmp>
+ void sync_priority_queue<T,Container,Cmp>::push(unique_lock<mutex>& lk, const T& elem)
+ {
+ super::throw_if_closed(lk);
+ super::data_.push(elem);
+ super::notify_not_empty_if_needed(lk);
+ }
+ template <class T, class Container,class Cmp>
+ void sync_priority_queue<T,Container,Cmp>::push(lock_guard<mutex>& lk, const T& elem)
+ {
+ super::throw_if_closed(lk);
+ super::data_.push(elem);
+ super::notify_not_empty_if_needed(lk);
+ }
+ template <class T, class Container,class Cmp>
+ void sync_priority_queue<T,Container,Cmp>::push(const T& elem)
+ {
+ lock_guard<mutex> lk(super::mtx_);
+ push(lk, elem);
+ }
+
+ //////////////////////
+ template <class T, class Container,class Cmp>
+ void sync_priority_queue<T,Container,Cmp>::push(unique_lock<mutex>& lk, BOOST_THREAD_RV_REF(T) elem)
+ {
+ super::throw_if_closed(lk);
+ super::data_.push(boost::move(elem));
+ super::notify_not_empty_if_needed(lk);
+ }
+ template <class T, class Container,class Cmp>
+ void sync_priority_queue<T,Container,Cmp>::push(lock_guard<mutex>& lk, BOOST_THREAD_RV_REF(T) elem)
+ {
+ super::throw_if_closed(lk);
+ super::data_.push(boost::move(elem));
+ super::notify_not_empty_if_needed(lk);
+ }
+ template <class T, class Container,class Cmp>
+ void sync_priority_queue<T,Container,Cmp>::push(BOOST_THREAD_RV_REF(T) elem)
+ {
+ lock_guard<mutex> lk(super::mtx_);
+ push(lk, boost::move(elem));
+ }
+
+ //////////////////////
+ template <class T, class Container,class Cmp>
+ queue_op_status sync_priority_queue<T,Container,Cmp>::try_push(const T& elem)
+ {
+ lock_guard<mutex> lk(super::mtx_);
+ if (super::closed(lk)) return queue_op_status::closed;
+ push(lk, elem);
+ return queue_op_status::success;
+ }
+
+ //////////////////////
+ template <class T, class Container,class Cmp>
+ queue_op_status sync_priority_queue<T,Container,Cmp>::try_push(BOOST_THREAD_RV_REF(T) elem)
+ {
+ lock_guard<mutex> lk(super::mtx_);
+ if (super::closed(lk)) return queue_op_status::closed;
+ push(lk, boost::move(elem));
+
+ return queue_op_status::success;
+ }
+
+ //////////////////////
+ template <class T,class Container, class Cmp>
+ T sync_priority_queue<T,Container,Cmp>::pull(unique_lock<mutex>&)
+ {
+ return super::data_.pull();
+ }
+ template <class T,class Container, class Cmp>
+ T sync_priority_queue<T,Container,Cmp>::pull(lock_guard<mutex>&)
+ {
+ return super::data_.pull();
+ }
+
+ template <class T,class Container, class Cmp>
+ T sync_priority_queue<T,Container,Cmp>::pull()
+ {
+ unique_lock<mutex> lk(super::mtx_);
+ super::wait_until_not_empty(lk);
+ return pull(lk);
+ }
+
+ //////////////////////
+ template <class T,class Container, class Cmp>
+ void sync_priority_queue<T,Container,Cmp>::pull(unique_lock<mutex>&, T& elem)
+ {
+ elem = super::data_.pull();
+ }
+ template <class T,class Container, class Cmp>
+ void sync_priority_queue<T,Container,Cmp>::pull(lock_guard<mutex>&, T& elem)
+ {
+ elem = super::data_.pull();
+ }
+
+ template <class T,class Container, class Cmp>
+ void sync_priority_queue<T,Container,Cmp>::pull(T& elem)
+ {
+ unique_lock<mutex> lk(super::mtx_);
+ super::wait_until_not_empty(lk);
+ pull(lk, elem);
+ }
+
+ //////////////////////
+ template <class T, class Cont,class Cmp>
+ queue_op_status
+ sync_priority_queue<T,Cont,Cmp>::pull_until(const clock::time_point& tp, T& elem)
+ {
+ unique_lock<mutex> lk(super::mtx_);
+ if (queue_op_status::timeout == super::wait_until_not_empty_until(lk, tp))
+ return queue_op_status::timeout;
+ pull(lk, elem);
+ return queue_op_status::success;
+ }
+
+ //////////////////////
+ template <class T, class Cont,class Cmp>
+ queue_op_status
+ sync_priority_queue<T,Cont,Cmp>::pull_for(const clock::duration& dura, T& elem)
+ {
+ return pull_until(clock::now() + dura, elem);
+ }
+
+ //////////////////////
+ template <class T, class Container,class Cmp>
+ queue_op_status
+ sync_priority_queue<T,Container,Cmp>::try_pull(unique_lock<mutex>& lk, T& elem)
+ {
+ if (super::empty(lk))
+ {
+ if (super::closed(lk)) return queue_op_status::closed;
+ return queue_op_status::empty;
+ }
+ pull(lk, elem);
+ return queue_op_status::success;
+ }
+
+ template <class T, class Container,class Cmp>
+ queue_op_status
+ sync_priority_queue<T,Container,Cmp>::try_pull(lock_guard<mutex>& lk, T& elem)
+ {
+ if (super::empty(lk))
+ {
+ if (super::closed(lk)) return queue_op_status::closed;
+ return queue_op_status::empty;
+ }
+ pull(lk, elem);
+ return queue_op_status::success;
+ }
+
+ template <class T, class Container,class Cmp>
+ queue_op_status
+ sync_priority_queue<T,Container,Cmp>::try_pull(T& elem)
+ {
+ lock_guard<mutex> lk(super::mtx_);
+ return try_pull(lk, elem);
+ }
+
+ //////////////////////
+ template <class T,class Container, class Cmp>
+ queue_op_status sync_priority_queue<T,Container,Cmp>::wait_pull(unique_lock<mutex>& lk, T& elem)
+ {
+ if (super::empty(lk))
+ {
+ if (super::closed(lk)) return queue_op_status::closed;
+ }
+ bool has_been_closed = super::wait_until_not_empty_or_closed(lk);
+ if (has_been_closed) return queue_op_status::closed;
+ pull(lk, elem);
+ return queue_op_status::success;
+ }
+
+ template <class T,class Container, class Cmp>
+ queue_op_status sync_priority_queue<T,Container,Cmp>::wait_pull(T& elem)
+ {
+ unique_lock<mutex> lk(super::mtx_);
+ return wait_pull(lk, elem);
+ }
+
+ //////////////////////
+
+ template <class T,class Container, class Cmp>
+ queue_op_status sync_priority_queue<T,Container,Cmp>::nonblocking_pull(T& elem)
+ {
+ unique_lock<mutex> lk(super::mtx_, try_to_lock);
+ if (!lk.owns_lock()) return queue_op_status::busy;
+ return try_pull(lk, elem);
+ }
+
+
+
+} //end concurrent namespace
+
+using concurrent::sync_priority_queue;
+
+} //end boost namespace
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/sync_queue.hpp b/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/sync_queue.hpp
new file mode 100644
index 00000000000..1dbbef05dd3
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/sync_queue.hpp
@@ -0,0 +1,335 @@
+#ifndef BOOST_THREAD_CONCURRENT_QUEUES_SYNC_QUEUE_HPP
+#define BOOST_THREAD_CONCURRENT_QUEUES_SYNC_QUEUE_HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2013-2014. Distributed under the 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 http://www.boost.org/libs/thread for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <iostream>
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/concurrent_queues/detail/sync_queue_base.hpp>
+#include <boost/thread/concurrent_queues/queue_op_status.hpp>
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/csbl/devector.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/mutex.hpp>
+
+#include <boost/throw_exception.hpp>
+#include <boost/smart_ptr/shared_ptr.hpp>
+#include <boost/smart_ptr/make_shared.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+namespace concurrent
+{
+ template <class ValueType, class Container = csbl::devector<ValueType> >
+ class sync_queue
+ : public detail::sync_queue_base<ValueType, Container >
+ {
+ typedef detail::sync_queue_base<ValueType, Container > super;
+
+ public:
+ typedef ValueType value_type;
+ //typedef typename super::value_type value_type; // fixme
+ typedef typename super::underlying_queue_type underlying_queue_type;
+ typedef typename super::size_type size_type;
+ typedef typename super::op_status op_status;
+
+ // Constructors/Assignment/Destructors
+ BOOST_THREAD_NO_COPYABLE(sync_queue)
+ inline sync_queue();
+ //template <class Range>
+ //inline explicit sync_queue(Range range);
+ inline ~sync_queue();
+
+ // Modifiers
+
+ inline void push(const value_type& x);
+ inline queue_op_status try_push(const value_type& x);
+ inline queue_op_status nonblocking_push(const value_type& x);
+ inline queue_op_status wait_push(const value_type& x);
+ inline void push(BOOST_THREAD_RV_REF(value_type) x);
+ inline queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x);
+ inline queue_op_status nonblocking_push(BOOST_THREAD_RV_REF(value_type) x);
+ inline queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x);
+
+ // Observers/Modifiers
+ inline void pull(value_type&);
+ // enable_if is_nothrow_copy_movable<value_type>
+ inline value_type pull();
+
+ inline queue_op_status try_pull(value_type&);
+ inline queue_op_status nonblocking_pull(value_type&);
+ inline queue_op_status wait_pull(ValueType& elem);
+
+ private:
+
+ inline queue_op_status try_pull(value_type& x, unique_lock<mutex>& lk);
+ inline queue_op_status wait_pull(value_type& x, unique_lock<mutex>& lk);
+ inline queue_op_status try_push(const value_type& x, unique_lock<mutex>& lk);
+ inline queue_op_status wait_push(const value_type& x, unique_lock<mutex>& lk);
+ inline queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x, unique_lock<mutex>& lk);
+ inline queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x, unique_lock<mutex>& lk);
+
+ inline void pull(value_type& elem, unique_lock<mutex>& )
+ {
+ elem = boost::move(super::data_.front());
+ super::data_.pop_front();
+ }
+ inline value_type pull(unique_lock<mutex>& )
+ {
+ value_type e = boost::move(super::data_.front());
+ super::data_.pop_front();
+ return boost::move(e);
+ }
+
+ inline void push(const value_type& elem, unique_lock<mutex>& lk)
+ {
+ super::data_.push_back(elem);
+ super::notify_not_empty_if_needed(lk);
+ }
+
+ inline void push(BOOST_THREAD_RV_REF(value_type) elem, unique_lock<mutex>& lk)
+ {
+ super::data_.push_back(boost::move(elem));
+ super::notify_not_empty_if_needed(lk);
+ }
+ };
+
+ template <class ValueType, class Container>
+ sync_queue<ValueType, Container>::sync_queue() :
+ super()
+ {
+ }
+
+// template <class ValueType, class Container>
+// template <class Range>
+// explicit sync_queue<ValueType, Container>::sync_queue(Range range) :
+// data_(), closed_(false)
+// {
+// try
+// {
+// typedef typename Range::iterator iterator_t;
+// iterator_t first = boost::begin(range);
+// iterator_t end = boost::end(range);
+// for (iterator_t cur = first; cur != end; ++cur)
+// {
+// data_.push(boost::move(*cur));;
+// }
+// notify_not_empty_if_needed(lk);
+// }
+// catch (...)
+// {
+// delete[] data_;
+// }
+// }
+
+ template <class ValueType, class Container>
+ sync_queue<ValueType, Container>::~sync_queue()
+ {
+ }
+
+ template <class ValueType, class Container>
+ queue_op_status sync_queue<ValueType, Container>::try_pull(ValueType& elem, unique_lock<mutex>& lk)
+ {
+ if (super::empty(lk))
+ {
+ if (super::closed(lk)) return queue_op_status::closed;
+ return queue_op_status::empty;
+ }
+ pull(elem, lk);
+ return queue_op_status::success;
+ }
+ template <class ValueType, class Container>
+ queue_op_status sync_queue<ValueType, Container>::wait_pull(ValueType& elem, unique_lock<mutex>& lk)
+ {
+ //std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ if (super::empty(lk))
+ {
+ //std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ if (super::closed(lk)) return queue_op_status::closed;
+ }
+ //std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ bool has_been_closed = super::wait_until_not_empty_or_closed(lk);
+ //std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ if (has_been_closed) return queue_op_status::closed;
+ //std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ pull(elem, lk);
+ //std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ return queue_op_status::success;
+ }
+
+ template <class ValueType, class Container>
+ queue_op_status sync_queue<ValueType, Container>::try_pull(ValueType& elem)
+ {
+ unique_lock<mutex> lk(super::mtx_);
+ return try_pull(elem, lk);
+ }
+
+ template <class ValueType, class Container>
+ queue_op_status sync_queue<ValueType, Container>::wait_pull(ValueType& elem)
+ {
+ unique_lock<mutex> lk(super::mtx_);
+ return wait_pull(elem, lk);
+ }
+
+ template <class ValueType, class Container>
+ queue_op_status sync_queue<ValueType, Container>::nonblocking_pull(ValueType& elem)
+ {
+ unique_lock<mutex> lk(super::mtx_, try_to_lock);
+ if (!lk.owns_lock())
+ {
+ return queue_op_status::busy;
+ }
+ return try_pull(elem, lk);
+ }
+
+ template <class ValueType, class Container>
+ void sync_queue<ValueType, Container>::pull(ValueType& elem)
+ {
+ unique_lock<mutex> lk(super::mtx_);
+ super::wait_until_not_empty(lk);
+ pull(elem, lk);
+ }
+
+ // enable if ValueType is nothrow movable
+ template <class ValueType, class Container>
+ ValueType sync_queue<ValueType, Container>::pull()
+ {
+ unique_lock<mutex> lk(super::mtx_);
+ super::wait_until_not_empty(lk);
+ return pull(lk);
+ }
+
+ template <class ValueType, class Container>
+ queue_op_status sync_queue<ValueType, Container>::try_push(const ValueType& elem, unique_lock<mutex>& lk)
+ {
+ if (super::closed(lk)) return queue_op_status::closed;
+ push(elem, lk);
+ return queue_op_status::success;
+ }
+
+ template <class ValueType, class Container>
+ queue_op_status sync_queue<ValueType, Container>::try_push(const ValueType& elem)
+ {
+ unique_lock<mutex> lk(super::mtx_);
+ return try_push(elem, lk);
+ }
+
+ template <class ValueType, class Container>
+ queue_op_status sync_queue<ValueType, Container>::wait_push(const ValueType& elem, unique_lock<mutex>& lk)
+ {
+ if (super::closed(lk)) return queue_op_status::closed;
+ push(elem, lk);
+ return queue_op_status::success;
+ }
+
+ template <class ValueType, class Container>
+ queue_op_status sync_queue<ValueType, Container>::wait_push(const ValueType& elem)
+ {
+ unique_lock<mutex> lk(super::mtx_);
+ return wait_push(elem, lk);
+ }
+
+ template <class ValueType, class Container>
+ queue_op_status sync_queue<ValueType, Container>::nonblocking_push(const ValueType& elem)
+ {
+ unique_lock<mutex> lk(super::mtx_, try_to_lock);
+ if (!lk.owns_lock()) return queue_op_status::busy;
+ return try_push(elem, lk);
+ }
+
+ template <class ValueType, class Container>
+ void sync_queue<ValueType, Container>::push(const ValueType& elem)
+ {
+ unique_lock<mutex> lk(super::mtx_);
+ super::throw_if_closed(lk);
+ push(elem, lk);
+ }
+
+ template <class ValueType, class Container>
+ queue_op_status sync_queue<ValueType, Container>::try_push(BOOST_THREAD_RV_REF(ValueType) elem, unique_lock<mutex>& lk)
+ {
+ if (super::closed(lk)) return queue_op_status::closed;
+ push(boost::move(elem), lk);
+ return queue_op_status::success;
+ }
+
+ template <class ValueType, class Container>
+ queue_op_status sync_queue<ValueType, Container>::try_push(BOOST_THREAD_RV_REF(ValueType) elem)
+ {
+ unique_lock<mutex> lk(super::mtx_);
+ return try_push(boost::move(elem), lk);
+ }
+
+ template <class ValueType, class Container>
+ queue_op_status sync_queue<ValueType, Container>::wait_push(BOOST_THREAD_RV_REF(ValueType) elem, unique_lock<mutex>& lk)
+ {
+ if (super::closed(lk)) return queue_op_status::closed;
+ push(boost::move(elem), lk);
+ return queue_op_status::success;
+ }
+
+ template <class ValueType, class Container>
+ queue_op_status sync_queue<ValueType, Container>::wait_push(BOOST_THREAD_RV_REF(ValueType) elem)
+ {
+ unique_lock<mutex> lk(super::mtx_);
+ return wait_push(boost::move(elem), lk);
+ }
+
+ template <class ValueType, class Container>
+ queue_op_status sync_queue<ValueType, Container>::nonblocking_push(BOOST_THREAD_RV_REF(ValueType) elem)
+ {
+ unique_lock<mutex> lk(super::mtx_, try_to_lock);
+ if (!lk.owns_lock())
+ {
+ return queue_op_status::busy;
+ }
+ return try_push(boost::move(elem), lk);
+ }
+
+ template <class ValueType, class Container>
+ void sync_queue<ValueType, Container>::push(BOOST_THREAD_RV_REF(ValueType) elem)
+ {
+ unique_lock<mutex> lk(super::mtx_);
+ super::throw_if_closed(lk);
+ push(boost::move(elem), lk);
+ }
+
+ template <class ValueType, class Container>
+ sync_queue<ValueType, Container>& operator<<(sync_queue<ValueType, Container>& sbq, BOOST_THREAD_RV_REF(ValueType) elem)
+ {
+ sbq.push(boost::move(elem));
+ return sbq;
+ }
+
+ template <class ValueType, class Container>
+ sync_queue<ValueType, Container>& operator<<(sync_queue<ValueType, Container>& sbq, ValueType const&elem)
+ {
+ sbq.push(elem);
+ return sbq;
+ }
+
+ template <class ValueType, class Container>
+ sync_queue<ValueType, Container>& operator>>(sync_queue<ValueType, Container>& sbq, ValueType &elem)
+ {
+ sbq.pull(elem);
+ return sbq;
+ }
+
+}
+using concurrent::sync_queue;
+
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/sync_timed_queue.hpp b/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/sync_timed_queue.hpp
new file mode 100644
index 00000000000..36223d87152
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/concurrent_queues/sync_timed_queue.hpp
@@ -0,0 +1,466 @@
+// 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)
+//
+
+#ifndef BOOST_THREAD_SYNC_TIMED_QUEUE_HPP
+#define BOOST_THREAD_SYNC_TIMED_QUEUE_HPP
+
+#include <boost/thread/detail/config.hpp>
+
+#include <boost/thread/concurrent_queues/sync_priority_queue.hpp>
+#include <boost/chrono/duration.hpp>
+#include <boost/chrono/time_point.hpp>
+#include <boost/chrono/system_clocks.hpp>
+#include <boost/chrono/chrono_io.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+namespace concurrent
+{
+namespace detail
+{
+ template <class T, class Clock = chrono::steady_clock>
+ struct scheduled_type
+ {
+ typedef T value_type;
+ typedef Clock clock;
+ typedef typename clock::time_point time_point;
+ T data;
+ time_point time;
+
+ BOOST_THREAD_COPYABLE_AND_MOVABLE(scheduled_type)
+
+ scheduled_type(T const& pdata, time_point tp) : data(pdata), time(tp) {}
+ scheduled_type(BOOST_THREAD_RV_REF(T) pdata, time_point tp) : data(boost::move(pdata)), time(tp) {}
+
+ scheduled_type(scheduled_type const& other) : data(other.data), time(other.time) {}
+ scheduled_type& operator=(BOOST_THREAD_COPY_ASSIGN_REF(scheduled_type) other) {
+ data = other.data;
+ time = other.time;
+ return *this;
+ }
+
+ scheduled_type(BOOST_THREAD_RV_REF(scheduled_type) other) : data(boost::move(other.data)), time(other.time) {}
+ scheduled_type& operator=(BOOST_THREAD_RV_REF(scheduled_type) other) {
+ data = boost::move(other.data);
+ time = other.time;
+ return *this;
+ }
+
+ bool time_not_reached() const
+ {
+ return time > clock::now();
+ }
+
+ bool operator <(const scheduled_type<T> other) const
+ {
+ return this->time > other.time;
+ }
+ }; //end struct
+
+} //end detail namespace
+
+ template <class T, class Clock = chrono::steady_clock>
+ class sync_timed_queue
+ : private sync_priority_queue<detail::scheduled_type<T, Clock> >
+ {
+ typedef detail::scheduled_type<T> stype;
+ typedef sync_priority_queue<stype> super;
+ public:
+ typedef T value_type;
+ typedef Clock clock;
+ typedef typename clock::duration duration;
+ typedef typename clock::time_point time_point;
+ typedef typename super::underlying_queue_type underlying_queue_type;
+ typedef typename super::size_type size_type;
+ typedef typename super::op_status op_status;
+
+ sync_timed_queue() : super() {};
+ ~sync_timed_queue() {}
+
+ using super::size;
+ using super::empty;
+ using super::full;
+ using super::close;
+ using super::closed;
+
+ T pull();
+ void pull(T& elem);
+
+ template <class Duration>
+ queue_op_status pull_until(chrono::time_point<clock,Duration> const& tp, T& elem);
+ template <class Rep, class Period>
+ queue_op_status pull_for(chrono::duration<Rep,Period> const& dura, T& elem);
+
+ queue_op_status try_pull(T& elem);
+ queue_op_status wait_pull(T& elem);
+ queue_op_status nonblocking_pull(T& elem);
+
+ template <class Duration>
+ void push(const T& elem, chrono::time_point<clock,Duration> const& tp);
+ template <class Rep, class Period>
+ void push(const T& elem, chrono::duration<Rep,Period> const& dura);
+
+ template <class Duration>
+ void push(BOOST_THREAD_RV_REF(T) elem, chrono::time_point<clock,Duration> const& tp);
+ template <class Rep, class Period>
+ void push(BOOST_THREAD_RV_REF(T) elem, chrono::duration<Rep,Period> const& dura);
+
+ template <class Duration>
+ queue_op_status try_push(const T& elem, chrono::time_point<clock,Duration> const& tp);
+ template <class Rep, class Period>
+ queue_op_status try_push(const T& elem, chrono::duration<Rep,Period> const& dura);
+
+ template <class Duration>
+ queue_op_status try_push(BOOST_THREAD_RV_REF(T) elem, chrono::time_point<clock,Duration> const& tp);
+ template <class Rep, class Period>
+ queue_op_status try_push(BOOST_THREAD_RV_REF(T) elem, chrono::duration<Rep,Period> const& dura);
+
+ private:
+ T pull(unique_lock<mutex>&);
+ T pull(lock_guard<mutex>&);
+
+ void pull(unique_lock<mutex>&, T& elem);
+ void pull(lock_guard<mutex>&, T& elem);
+
+ queue_op_status try_pull(unique_lock<mutex>&, T& elem);
+ queue_op_status try_pull(lock_guard<mutex>&, T& elem);
+
+ queue_op_status wait_pull(unique_lock<mutex>& lk, T& elem);
+
+ bool wait_until_not_empty_time_reached_or_closed(unique_lock<mutex>&);
+ T pull_when_time_reached(unique_lock<mutex>&);
+ template <class Duration>
+ queue_op_status pull_when_time_reached_until(unique_lock<mutex>&, chrono::time_point<clock,Duration> const& tp, T& elem);
+ bool time_not_reached(unique_lock<mutex>&);
+ bool time_not_reached(lock_guard<mutex>&);
+ bool empty_or_time_not_reached(unique_lock<mutex>&);
+ bool empty_or_time_not_reached(lock_guard<mutex>&);
+
+ sync_timed_queue(const sync_timed_queue&);
+ sync_timed_queue& operator=(const sync_timed_queue&);
+ sync_timed_queue(BOOST_THREAD_RV_REF(sync_timed_queue));
+ sync_timed_queue& operator=(BOOST_THREAD_RV_REF(sync_timed_queue));
+ }; //end class
+
+
+ template <class T, class Clock>
+ template <class Duration>
+ void sync_timed_queue<T, Clock>::push(const T& elem, chrono::time_point<clock,Duration> const& tp)
+ {
+ super::push(stype(elem,tp));
+ }
+
+ template <class T, class Clock>
+ template <class Rep, class Period>
+ void sync_timed_queue<T, Clock>::push(const T& elem, chrono::duration<Rep,Period> const& dura)
+ {
+ push(elem, clock::now() + dura);
+ }
+
+ template <class T, class Clock>
+ template <class Duration>
+ void sync_timed_queue<T, Clock>::push(BOOST_THREAD_RV_REF(T) elem, chrono::time_point<clock,Duration> const& tp)
+ {
+ super::push(stype(boost::move(elem),tp));
+ }
+
+ template <class T, class Clock>
+ template <class Rep, class Period>
+ void sync_timed_queue<T, Clock>::push(BOOST_THREAD_RV_REF(T) elem, chrono::duration<Rep,Period> const& dura)
+ {
+ push(boost::move(elem), clock::now() + dura);
+ }
+
+
+
+ template <class T, class Clock>
+ template <class Duration>
+ queue_op_status sync_timed_queue<T, Clock>::try_push(const T& elem, chrono::time_point<clock,Duration> const& tp)
+ {
+ return super::try_push(stype(elem,tp));
+ }
+
+ template <class T, class Clock>
+ template <class Rep, class Period>
+ queue_op_status sync_timed_queue<T, Clock>::try_push(const T& elem, chrono::duration<Rep,Period> const& dura)
+ {
+ return try_push(elem,clock::now() + dura);
+ }
+
+ template <class T, class Clock>
+ template <class Duration>
+ queue_op_status sync_timed_queue<T, Clock>::try_push(BOOST_THREAD_RV_REF(T) elem, chrono::time_point<clock,Duration> const& tp)
+ {
+ return super::try_push(stype(boost::move(elem), tp));
+ }
+
+ template <class T, class Clock>
+ template <class Rep, class Period>
+ queue_op_status sync_timed_queue<T, Clock>::try_push(BOOST_THREAD_RV_REF(T) elem, chrono::duration<Rep,Period> const& dura)
+ {
+ return try_push(boost::move(elem), clock::now() + dura);
+ }
+
+ ///////////////////////////
+ template <class T, class Clock>
+ bool sync_timed_queue<T, Clock>::time_not_reached(unique_lock<mutex>&)
+ {
+ return super::data_.top().time_not_reached();
+ }
+
+ template <class T, class Clock>
+ bool sync_timed_queue<T, Clock>::time_not_reached(lock_guard<mutex>&)
+ {
+ return super::data_.top().time_not_reached();
+ }
+
+ ///////////////////////////
+ template <class T, class Clock>
+ bool sync_timed_queue<T, Clock>::wait_until_not_empty_time_reached_or_closed(unique_lock<mutex>& lk)
+ {
+ for (;;)
+ {
+ if (super::closed(lk)) return true;
+ while (! super::empty(lk)) {
+ if (! time_not_reached(lk)) return false;
+ super::not_empty_.wait_until(lk, super::data_.top().time);
+ if (super::closed(lk)) return true;
+ }
+ if (super::closed(lk)) return true;
+ super::not_empty_.wait(lk);
+ }
+ //return false;
+ }
+
+ ///////////////////////////
+ template <class T, class Clock>
+ T sync_timed_queue<T, Clock>::pull_when_time_reached(unique_lock<mutex>& lk)
+ {
+ while (time_not_reached(lk))
+ {
+ super::throw_if_closed(lk);
+ super::not_empty_.wait_until(lk,super::data_.top().time);
+ super::wait_until_not_empty(lk);
+ }
+ return pull(lk);
+ }
+
+ template <class T, class Clock>
+ template <class Duration>
+ queue_op_status
+ sync_timed_queue<T, Clock>::pull_when_time_reached_until(unique_lock<mutex>& lk, chrono::time_point<clock,Duration> const& tp, T& elem)
+ {
+ chrono::time_point<clock,Duration> tpmin = (tp < super::data_.top().time) ? tp : super::data_.top().time;
+ while (time_not_reached(lk))
+ {
+ super::throw_if_closed(lk);
+ if (queue_op_status::timeout == super::not_empty_.wait_until(lk, tpmin)) {
+ if (time_not_reached(lk)) return queue_op_status::not_ready;
+ return queue_op_status::timeout;
+ }
+ }
+ pull(lk, elem);
+ return queue_op_status::success;
+ }
+
+ ///////////////////////////
+ template <class T, class Clock>
+ bool sync_timed_queue<T, Clock>::empty_or_time_not_reached(unique_lock<mutex>& lk)
+ {
+ if ( super::empty(lk) ) return true;
+ if ( time_not_reached(lk) ) return true;
+ return false;
+ }
+ template <class T, class Clock>
+ bool sync_timed_queue<T, Clock>::empty_or_time_not_reached(lock_guard<mutex>& lk)
+ {
+ if ( super::empty(lk) ) return true;
+ if ( time_not_reached(lk) ) return true;
+ return false;
+ }
+
+ ///////////////////////////
+ template <class T, class Clock>
+ T sync_timed_queue<T, Clock>::pull(unique_lock<mutex>&)
+ {
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ return boost::move(super::data_.pull().data);
+#else
+ return super::data_.pull().data;
+#endif
+ }
+
+ template <class T, class Clock>
+ T sync_timed_queue<T, Clock>::pull(lock_guard<mutex>&)
+ {
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ return boost::move(super::data_.pull().data);
+#else
+ return super::data_.pull().data;
+#endif
+ }
+ template <class T, class Clock>
+ T sync_timed_queue<T, Clock>::pull()
+ {
+ unique_lock<mutex> lk(super::mtx_);
+ super::wait_until_not_empty(lk);
+ return pull_when_time_reached(lk);
+ }
+
+ ///////////////////////////
+ template <class T, class Clock>
+ void sync_timed_queue<T, Clock>::pull(unique_lock<mutex>&, T& elem)
+ {
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ elem = boost::move(super::data_.pull().data);
+#else
+ elem = super::data_.pull().data;
+#endif
+ }
+
+ template <class T, class Clock>
+ void sync_timed_queue<T, Clock>::pull(lock_guard<mutex>&, T& elem)
+ {
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ elem = boost::move(super::data_.pull().data);
+#else
+ elem = super::data_.pull().data;
+#endif
+ }
+
+ template <class T, class Clock>
+ void sync_timed_queue<T, Clock>::pull(T& elem)
+ {
+ unique_lock<mutex> lk(super::mtx_);
+ super::wait_until_not_empty(lk);
+ elem = pull_when_time_reached(lk);
+ }
+
+ //////////////////////
+ template <class T, class Clock>
+ template <class Duration>
+ queue_op_status
+ sync_timed_queue<T, Clock>::pull_until(chrono::time_point<clock,Duration> const& tp, T& elem)
+ {
+ unique_lock<mutex> lk(super::mtx_);
+
+ if (queue_op_status::timeout == super::wait_until_not_empty_until(lk, tp))
+ return queue_op_status::timeout;
+ return pull_when_time_reached_until(lk, tp, elem);
+ }
+
+ //////////////////////
+ template <class T, class Clock>
+ template <class Rep, class Period>
+ queue_op_status
+ sync_timed_queue<T, Clock>::pull_for(chrono::duration<Rep,Period> const& dura, T& elem)
+ {
+ return pull_until(clock::now() + dura, elem);
+ }
+
+ ///////////////////////////
+ template <class T, class Clock>
+ queue_op_status sync_timed_queue<T, Clock>::try_pull(unique_lock<mutex>& lk, T& elem)
+ {
+ if ( super::empty(lk) )
+ {
+ if (super::closed(lk)) return queue_op_status::closed;
+ return queue_op_status::empty;
+ }
+ if ( time_not_reached(lk) )
+ {
+ if (super::closed(lk)) return queue_op_status::closed;
+ return queue_op_status::not_ready;
+ }
+
+ pull(lk, elem);
+ return queue_op_status::success;
+ }
+ template <class T, class Clock>
+ queue_op_status sync_timed_queue<T, Clock>::try_pull(lock_guard<mutex>& lk, T& elem)
+ {
+ if ( super::empty(lk) )
+ {
+ if (super::closed(lk)) return queue_op_status::closed;
+ return queue_op_status::empty;
+ }
+ if ( time_not_reached(lk) )
+ {
+ if (super::closed(lk)) return queue_op_status::closed;
+ return queue_op_status::not_ready;
+ }
+ pull(lk, elem);
+ return queue_op_status::success;
+ }
+
+ template <class T, class Clock>
+ queue_op_status sync_timed_queue<T, Clock>::try_pull(T& elem)
+ {
+ lock_guard<mutex> lk(super::mtx_);
+ return try_pull(lk, elem);
+ }
+
+ ///////////////////////////
+ template <class T, class Clock>
+ queue_op_status sync_timed_queue<T, Clock>::wait_pull(unique_lock<mutex>& lk, T& elem)
+ {
+ if (super::empty(lk))
+ {
+ if (super::closed(lk)) return queue_op_status::closed;
+ }
+ bool has_been_closed = wait_until_not_empty_time_reached_or_closed(lk);
+ if (has_been_closed) return queue_op_status::closed;
+ pull(lk, elem);
+ return queue_op_status::success;
+ }
+
+ template <class T, class Clock>
+ queue_op_status sync_timed_queue<T, Clock>::wait_pull(T& elem)
+ {
+ unique_lock<mutex> lk(super::mtx_);
+ return wait_pull(lk, elem);
+ }
+
+// ///////////////////////////
+// template <class T, class Clock>
+// queue_op_status sync_timed_queue<T, Clock>::wait_pull(unique_lock<mutex> &lk, T& elem)
+// {
+// if (super::empty(lk))
+// {
+// if (super::closed(lk)) return queue_op_status::closed;
+// }
+// bool has_been_closed = super::wait_until_not_empty_or_closed(lk);
+// if (has_been_closed) return queue_op_status::closed;
+// pull(lk, elem);
+// return queue_op_status::success;
+// }
+// template <class T>
+// queue_op_status sync_timed_queue<T, Clock>::wait_pull(T& elem)
+// {
+// unique_lock<mutex> lk(super::mtx_);
+// return wait_pull(lk, elem);
+// }
+
+ ///////////////////////////
+ template <class T, class Clock>
+ queue_op_status sync_timed_queue<T, Clock>::nonblocking_pull(T& elem)
+ {
+ unique_lock<mutex> lk(super::mtx_, try_to_lock);
+ if (! lk.owns_lock()) return queue_op_status::busy;
+ return try_pull(lk, elem);
+ }
+
+} //end concurrent namespace
+
+using concurrent::sync_timed_queue;
+
+} //end boost namespace
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/condition.hpp b/src/third_party/boost-1.60.0/boost/thread/condition.hpp
new file mode 100644
index 00000000000..9567df98251
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/condition.hpp
@@ -0,0 +1,21 @@
+#ifndef BOOST_THREAD_CONDITION_HPP
+#define BOOST_THREAD_CONDITION_HPP
+// (C) Copyright 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/detail/config.hpp>
+
+#if defined BOOST_THREAD_PROVIDES_CONDITION
+
+#include <boost/thread/condition_variable.hpp>
+
+namespace boost
+{
+ typedef condition_variable_any condition;
+}
+
+#endif
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/condition_variable.hpp b/src/third_party/boost-1.60.0/boost/thread/condition_variable.hpp
new file mode 100644
index 00000000000..8f8e9f2ed65
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/condition_variable.hpp
@@ -0,0 +1,21 @@
+#ifndef BOOST_THREAD_CONDITION_VARIABLE_HPP
+#define BOOST_THREAD_CONDITION_VARIABLE_HPP
+
+// condition_variable.hpp
+//
+// (C) Copyright 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/detail/platform.hpp>
+#if defined(BOOST_THREAD_PLATFORM_WIN32)
+#include <boost/thread/win32/condition_variable.hpp>
+#elif defined(BOOST_THREAD_PLATFORM_PTHREAD)
+#include <boost/thread/pthread/condition_variable.hpp>
+#else
+#error "Boost threads unavailable on this platform"
+#endif
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/csbl/deque.hpp b/src/third_party/boost-1.60.0/boost/thread/csbl/deque.hpp
new file mode 100644
index 00000000000..2b26a46e1ac
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/csbl/deque.hpp
@@ -0,0 +1,45 @@
+// 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)
+//
+// 2013/10 Vicente J. Botet Escriba
+// Creation.
+
+#ifndef BOOST_CSBL_DEQUE_HPP
+#define BOOST_CSBL_DEQUE_HPP
+
+#include <boost/config.hpp>
+// MSVC has some trouble instantiating a non_copyable type
+//C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xmemory0(606) : error C2248: 'non_copyable::non_copyable' : cannot access private member declared in class 'non_copyable'
+// ..\libs\thread\test\sync\mutual_exclusion\queue_views\single_thread_pass.cpp(24) : see declaration of 'non_copyable::non_copyable'
+// ..\libs\thread\test\sync\mutual_exclusion\queue_views\single_thread_pass.cpp(23) : see declaration of 'non_copyable'
+// C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xmemory0(605) : while compiling class template member function 'void std::allocator<_Ty>::construct(_Ty *,const _Ty &)'
+// with
+// [
+// _Ty=non_copyable
+// ]
+#if defined BOOST_THREAD_USES_BOOST_DEQUE || defined BOOST_NO_CXX11_RVALUE_REFERENCES || (defined _MSC_VER && _MSC_FULL_VER < 180020827)
+#ifndef BOOST_THREAD_USES_BOOST_DEQUE
+#define BOOST_THREAD_USES_BOOST_DEQUE
+#endif
+#include <boost/container/deque.hpp>
+#else
+#include <deque>
+#endif
+
+namespace boost
+{
+ namespace csbl
+ {
+#if defined BOOST_THREAD_USES_BOOST_DEQUE
+ using ::boost::container::deque;
+
+#else
+ using ::std::deque;
+
+#endif
+
+ }
+}
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/csbl/devector.hpp b/src/third_party/boost-1.60.0/boost/thread/csbl/devector.hpp
new file mode 100644
index 00000000000..c2bc0bbe992
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/csbl/devector.hpp
@@ -0,0 +1,102 @@
+// 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)
+//
+// 2013/10 Vicente J. Botet Escriba
+// Creation.
+
+#ifndef BOOST_CSBL_DEVECTOR_HPP
+#define BOOST_CSBL_DEVECTOR_HPP
+
+#include <boost/config.hpp>
+
+#include <boost/thread/csbl/vector.hpp>
+#include <boost/move/detail/move_helpers.hpp>
+
+namespace boost
+{
+ namespace csbl
+ {
+ template <class T>
+ class devector
+ {
+ typedef csbl::vector<T> vector_type;
+ vector_type data_;
+ std::size_t front_index_;
+
+ BOOST_COPYABLE_AND_MOVABLE(devector)
+
+ template <class U>
+ void priv_push_back(BOOST_FWD_REF(U) x)
+ { data_.push_back(boost::forward<U>(x)); }
+
+ public:
+ typedef typename vector_type::size_type size_type;
+ typedef typename vector_type::reference reference;
+ typedef typename vector_type::const_reference const_reference;
+
+
+ devector() : front_index_(0) {}
+ devector(devector const& x) BOOST_NOEXCEPT
+ : data_(x.data_),
+ front_index_(x.front_index_)
+ {}
+ devector(BOOST_RV_REF(devector) x) BOOST_NOEXCEPT
+ : data_(boost::move(x.data_)),
+ front_index_(x.front_index_)
+ {}
+
+ devector& operator=(BOOST_COPY_ASSIGN_REF(devector) x)
+ {
+ if (&x != this)
+ {
+ data_ = x.data_;
+ front_index_ = x.front_index_;
+ }
+ return *this;
+ }
+
+ devector& operator=(BOOST_RV_REF(devector) x)
+#if defined BOOST_THREAD_USES_BOOST_VECTOR
+ BOOST_NOEXCEPT_IF(vector_type::allocator_traits_type::propagate_on_container_move_assignment::value)
+#endif
+ {
+ data_ = boost::move(x.data_);
+ front_index_ = x.front_index_;
+ return *this;
+ }
+
+ bool empty() const BOOST_NOEXCEPT
+ { return data_.size() == front_index_; }
+
+ size_type size() const BOOST_NOEXCEPT
+ { return data_.size() - front_index_; }
+
+ reference front() BOOST_NOEXCEPT
+ { return data_[front_index_]; }
+
+ const_reference front() const BOOST_NOEXCEPT
+ { return data_[front_index_]; }
+
+ reference back() BOOST_NOEXCEPT
+ { return data_.back(); }
+
+ const_reference back() const BOOST_NOEXCEPT
+ { return data_.back(); }
+
+ BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back)
+
+ void pop_front()
+ {
+ ++front_index_;
+ if (empty()) {
+ data_.clear();
+ front_index_=0;
+ }
+ }
+
+ };
+ }
+}
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/csbl/functional.hpp b/src/third_party/boost-1.60.0/boost/thread/csbl/functional.hpp
new file mode 100644
index 00000000000..7a7e928b70f
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/csbl/functional.hpp
@@ -0,0 +1,49 @@
+// 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)
+//
+// 2013/10 Vicente J. Botet Escriba
+// Creation.
+
+#ifndef BOOST_CSBL_FUNCTIONAL_HPP
+#define BOOST_CSBL_FUNCTIONAL_HPP
+
+#include <boost/config.hpp>
+
+#include <functional>
+
+#if defined BOOST_THREAD_USES_BOOST_FUNCTIONAL || defined BOOST_NO_CXX11_HDR_FUNCTIONAL || defined BOOST_NO_CXX11_RVALUE_REFERENCES
+#ifndef BOOST_THREAD_USES_BOOST_FUNCTIONAL
+#define BOOST_THREAD_USES_BOOST_FUNCTIONAL
+#endif
+#include <boost/function.hpp>
+#endif
+
+namespace boost
+{
+ namespace csbl
+ {
+#if defined BOOST_THREAD_USES_BOOST_FUNCTIONAL
+ using ::boost::function;
+#else
+ // D.8.1, base (deprecated):
+ // 20.9.3, reference_wrapper:
+ // 20.9.4, arithmetic operations:
+ // 20.9.5, comparisons:
+ // 20.9.6, logical operations:
+ // 20.9.7, bitwise operations:
+ // 20.9.8, negators:
+ // 20.9.9, bind:
+ // D.9, binders (deprecated):
+ // D.8.2.1, adaptors (deprecated):
+ // D.8.2.2, adaptors (deprecated):
+ // 20.9.10, member function adaptors:
+ // 20.9.11 polymorphic function wrappers:
+ using ::std::function;
+ // 20.9.12, hash function primary template:
+#endif
+
+ }
+}
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/csbl/list.hpp b/src/third_party/boost-1.60.0/boost/thread/csbl/list.hpp
new file mode 100644
index 00000000000..52ff45d3497
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/csbl/list.hpp
@@ -0,0 +1,35 @@
+// 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)
+//
+// 2013/10 Vicente J. Botet Escriba
+// Creation.
+
+#ifndef BOOST_CSBL_LIST_HPP
+#define BOOST_CSBL_LIST_HPP
+
+#include <boost/config.hpp>
+
+#if defined BOOST_THREAD_USES_BOOST_LIST || defined BOOST_NO_CXX11_RVALUE_REFERENCES
+#ifndef BOOST_THREAD_USES_BOOST_LIST
+#define BOOST_THREAD_USES_BOOST_LIST
+#endif
+#include <boost/container/list.hpp>
+#else
+#include <list>
+#endif
+
+namespace boost
+{
+ namespace csbl
+ {
+#if defined BOOST_THREAD_USES_BOOST_LIST
+ using ::boost::container::list;
+#else
+ using ::std::list;
+#endif
+
+ }
+}
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/csbl/memory.hpp b/src/third_party/boost-1.60.0/boost/thread/csbl/memory.hpp
new file mode 100644
index 00000000000..e076f11ad30
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/csbl/memory.hpp
@@ -0,0 +1,61 @@
+// 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)
+//
+// 2013/10 Vicente J. Botet Escriba
+// Creation.
+
+#ifndef BOOST_CSBL_MEMORY_HPP
+#define BOOST_CSBL_MEMORY_HPP
+
+// 20.7.2 Header <memory> synopsis
+
+// 20.7.3, pointer traits
+#include <boost/thread/csbl/memory/pointer_traits.hpp>
+
+// 20.7.4, pointer safety
+// 20.7.5, pointer alignment function
+
+// 20.7.6, allocator argument tag
+#include <boost/thread/csbl/memory/allocator_arg.hpp>
+
+// 20.7.8, allocator traits
+#include <boost/thread/csbl/memory/allocator_traits.hpp>
+
+// 20.7.7, uses_allocator
+#include <boost/thread/csbl/memory/scoped_allocator.hpp>
+
+// 20.7.9, the default allocator:
+namespace boost
+{
+ namespace csbl
+ {
+ using ::std::allocator;
+ }
+}
+// 20.7.10, raw storage iterator:
+// 20.7.11, temporary buffers:
+// 20.7.12, specialized algorithms:
+
+// 20.8.1 class template unique_ptr:
+// default_delete
+#include <boost/thread/csbl/memory/default_delete.hpp>
+#include <boost/thread/csbl/memory/unique_ptr.hpp>
+
+// 20.8.2.1, class bad_weak_ptr:
+// 20.8.2.2, class template shared_ptr:
+// 20.8.2.2.6, shared_ptr creation
+// 20.8.2.2.7, shared_ptr comparisons:
+// 20.8.2.2.8, shared_ptr specialized algorithms:
+// 20.8.2.2.9, shared_ptr casts:
+// 20.8.2.2.10, shared_ptr get_deleter:
+// 20.8.2.2.11, shared_ptr I/O:
+// 20.8.2.3, class template weak_ptr:
+// 20.8.2.3.6, weak_ptr specialized algorithms:
+// 20.8.2.3.7, class template owner_less:
+// 20.8.2.4, class template enable_shared_from_this:
+// 20.8.2.5, shared_ptr atomic access:
+// 20.8.2.6 hash support
+
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/csbl/memory/allocator_arg.hpp b/src/third_party/boost-1.60.0/boost/thread/csbl/memory/allocator_arg.hpp
new file mode 100644
index 00000000000..354cdaee885
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/csbl/memory/allocator_arg.hpp
@@ -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)
+//
+// 2013/10 Vicente J. Botet Escriba
+// Creation.
+
+#ifndef BOOST_CSBL_MEMORY_ALLOCATOR_ARG_HPP
+#define BOOST_CSBL_MEMORY_ALLOCATOR_ARG_HPP
+
+#include <boost/thread/csbl/memory/config.hpp>
+
+// 20.7.6, allocator argument tag
+#if defined BOOST_NO_CXX11_ALLOCATOR
+#include <boost/container/scoped_allocator.hpp>
+
+namespace boost
+{
+ namespace csbl
+ {
+ using ::boost::container::allocator_arg_t;
+ using ::boost::container::allocator_arg;
+ }
+}
+#else
+namespace boost
+{
+ namespace csbl
+ {
+ using ::std::allocator_arg_t;
+ using ::std::allocator_arg;
+ }
+}
+#endif // BOOST_NO_CXX11_ALLOCATOR
+namespace boost
+{
+ using ::boost::csbl::allocator_arg_t;
+ using ::boost::csbl::allocator_arg;
+}
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/csbl/memory/allocator_traits.hpp b/src/third_party/boost-1.60.0/boost/thread/csbl/memory/allocator_traits.hpp
new file mode 100644
index 00000000000..3737cd85def
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/csbl/memory/allocator_traits.hpp
@@ -0,0 +1,35 @@
+// 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)
+//
+// 2013/10 Vicente J. Botet Escriba
+// Creation.
+
+#ifndef BOOST_CSBL_MEMORY_ALLOCATOR_TRAITS_HPP
+#define BOOST_CSBL_MEMORY_ALLOCATOR_TRAITS_HPP
+
+#include <boost/thread/csbl/memory/config.hpp>
+
+// 20.7.8, allocator traits
+#if defined BOOST_NO_CXX11_ALLOCATOR
+#include <boost/container/allocator_traits.hpp>
+
+namespace boost
+{
+ namespace csbl
+ {
+ using ::boost::container::allocator_traits;
+ }
+}
+#else
+namespace boost
+{
+ namespace csbl
+ {
+ using ::std::allocator_traits;
+ }
+}
+#endif // BOOST_NO_CXX11_POINTER_TRAITS
+
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/csbl/memory/config.hpp b/src/third_party/boost-1.60.0/boost/thread/csbl/memory/config.hpp
new file mode 100644
index 00000000000..7b0596ac490
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/csbl/memory/config.hpp
@@ -0,0 +1,16 @@
+// 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)
+//
+// 2013/10 Vicente J. Botet Escriba
+// Creation.
+
+#ifndef BOOST_CSBL_MEMORY_CONFIG_HPP
+#define BOOST_CSBL_MEMORY_CONFIG_HPP
+
+#include <boost/config.hpp>
+
+#include <memory>
+
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/csbl/memory/default_delete.hpp b/src/third_party/boost-1.60.0/boost/thread/csbl/memory/default_delete.hpp
new file mode 100644
index 00000000000..d20153b3096
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/csbl/memory/default_delete.hpp
@@ -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)
+//
+// 2013/10 Vicente J. Botet Escriba
+// Creation.
+
+#ifndef BOOST_CSBL_MEMORY_DEFAULT_DELETE_HPP
+#define BOOST_CSBL_MEMORY_DEFAULT_DELETE_HPP
+
+#include <boost/thread/csbl/memory/config.hpp>
+
+// 20.8.1 class template unique_ptr:
+// default_delete
+
+#if defined BOOST_NO_CXX11_SMART_PTR
+#include <boost/move/unique_ptr.hpp>
+
+namespace boost
+{
+ namespace csbl
+ {
+ using ::boost::movelib::default_delete;
+ }
+}
+#else
+namespace boost
+{
+ namespace csbl
+ {
+ using ::std::default_delete;
+ }
+}
+#endif // defined BOOST_NO_CXX11_SMART_PTR
+
+namespace boost
+{
+ using ::boost::csbl::default_delete;
+}
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/csbl/memory/pointer_traits.hpp b/src/third_party/boost-1.60.0/boost/thread/csbl/memory/pointer_traits.hpp
new file mode 100644
index 00000000000..320f8e9e774
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/csbl/memory/pointer_traits.hpp
@@ -0,0 +1,35 @@
+// 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)
+//
+// 2013/10 Vicente J. Botet Escriba
+// Creation.
+
+#ifndef BOOST_CSBL_MEMORY_POINTER_TRAITS_HPP
+#define BOOST_CSBL_MEMORY_POINTER_TRAITS_HPP
+
+#include <boost/thread/csbl/memory/config.hpp>
+
+// 20.7.3, pointer traits
+#if defined BOOST_NO_CXX11_ALLOCATOR
+#include <boost/intrusive/pointer_traits.hpp>
+
+namespace boost
+{
+ namespace csbl
+ {
+ using ::boost::intrusive::pointer_traits;
+ }
+}
+#else
+namespace boost
+{
+ namespace csbl
+ {
+ using ::std::pointer_traits;
+ }
+}
+#endif // BOOST_NO_CXX11_ALLOCATOR
+
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/csbl/memory/scoped_allocator.hpp b/src/third_party/boost-1.60.0/boost/thread/csbl/memory/scoped_allocator.hpp
new file mode 100644
index 00000000000..a92f3d85146
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/csbl/memory/scoped_allocator.hpp
@@ -0,0 +1,35 @@
+// 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)
+//
+// 2013/10 Vicente J. Botet Escriba
+// Creation.
+
+#ifndef BOOST_CSBL_MEMORY_SCOPED_ALLOCATOR_HPP
+#define BOOST_CSBL_MEMORY_SCOPED_ALLOCATOR_HPP
+
+#include <boost/thread/csbl/memory/config.hpp>
+
+// 20.7.7, uses_allocator
+#if defined BOOST_NO_CXX11_ALLOCATOR
+#include <boost/container/scoped_allocator.hpp>
+
+namespace boost
+{
+ namespace csbl
+ {
+ using ::boost::container::uses_allocator;
+ }
+}
+#else
+namespace boost
+{
+ namespace csbl
+ {
+ using ::std::uses_allocator;
+ }
+}
+#endif // BOOST_NO_CXX11_POINTER_TRAITS
+
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/csbl/memory/shared_ptr.hpp b/src/third_party/boost-1.60.0/boost/thread/csbl/memory/shared_ptr.hpp
new file mode 100644
index 00000000000..e9a9383723a
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/csbl/memory/shared_ptr.hpp
@@ -0,0 +1,42 @@
+// 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)
+//
+// 2014/10 Vicente J. Botet Escriba
+// Creation.
+
+#ifndef BOOST_CSBL_MEMORY_SHARED_PTR_HPP
+#define BOOST_CSBL_MEMORY_SHARED_PTR_HPP
+
+#include <boost/thread/csbl/memory/config.hpp>
+
+#if defined BOOST_NO_CXX11_SMART_PTR
+
+#include <boost/smart_ptr/shared_ptr.hpp>
+#include <boost/smart_ptr/make_shared.hpp>
+
+namespace boost
+{
+ namespace csbl
+ {
+ using ::boost::shared_ptr;
+ using ::boost::make_shared;
+ }
+}
+
+#else
+
+#include <boost/shared_ptr.hpp>
+
+namespace boost
+{
+ namespace csbl
+ {
+ using std::shared_ptr;
+ using std::make_shared;
+ }
+}
+
+#endif
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/csbl/memory/unique_ptr.hpp b/src/third_party/boost-1.60.0/boost/thread/csbl/memory/unique_ptr.hpp
new file mode 100644
index 00000000000..17abf54e92a
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/csbl/memory/unique_ptr.hpp
@@ -0,0 +1,28 @@
+// Copyright (C) 2013-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)
+//
+// 2013/10 Vicente J. Botet Escriba
+// Creation using interprocess::unique_ptr.
+// 2014/09 Vicente J. Botet Escriba
+// Adaptation to movelib::unique_ptr
+
+#ifndef BOOST_CSBL_MEMORY_UNIQUE_PTR_HPP
+#define BOOST_CSBL_MEMORY_UNIQUE_PTR_HPP
+
+#include <boost/thread/csbl/memory/config.hpp>
+
+#include <boost/move/unique_ptr.hpp>
+#include <boost/move/make_unique.hpp>
+
+namespace boost
+{
+ namespace csbl
+ {
+ using ::boost::movelib::unique_ptr;
+ using ::boost::movelib::make_unique;
+
+ }
+}
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/csbl/queue.hpp b/src/third_party/boost-1.60.0/boost/thread/csbl/queue.hpp
new file mode 100644
index 00000000000..1aa645d18fb
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/csbl/queue.hpp
@@ -0,0 +1,45 @@
+// Copyright (C) 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)
+//
+// 2013/10 Vicente J. Botet Escriba
+// Creation.
+
+#ifndef BOOST_CSBL_QUEUE_HPP
+#define BOOST_CSBL_QUEUE_HPP
+
+#include <boost/config.hpp>
+// MSVC has some trouble instantiating a non_copyable type
+//C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xmemory0(606) : error C2248: 'non_copyable::non_copyable' : cannot access private member declared in class 'non_copyable'
+// ..\libs\thread\test\sync\mutual_exclusion\queue_views\single_thread_pass.cpp(24) : see declaration of 'non_copyable::non_copyable'
+// ..\libs\thread\test\sync\mutual_exclusion\queue_views\single_thread_pass.cpp(23) : see declaration of 'non_copyable'
+// C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xmemory0(605) : while compiling class template member function 'void std::allocator<_Ty>::construct(_Ty *,const _Ty &)'
+// with
+// [
+// _Ty=non_copyable
+// ]
+#if defined BOOST_THREAD_USES_BOOST_QUEUE || defined BOOST_NO_CXX11_RVALUE_REFERENCES || (defined _MSC_VER && _MSC_FULL_VER < 180020827)
+#ifndef BOOST_THREAD_USES_BOOST_QUEUE
+#define BOOST_THREAD_USES_BOOST_QUEUE
+#endif
+#include <boost/container/queue.hpp>
+#else
+#include <queue>
+#endif
+
+namespace boost
+{
+ namespace csbl
+ {
+#if defined BOOST_THREAD_USES_BOOST_QUEUE
+ using ::boost::container::queue;
+
+#else
+ using ::std::queue;
+
+#endif
+
+ }
+}
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/csbl/tuple.hpp b/src/third_party/boost-1.60.0/boost/thread/csbl/tuple.hpp
new file mode 100644
index 00000000000..860229ebe0b
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/csbl/tuple.hpp
@@ -0,0 +1,49 @@
+// 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)
+//
+// 2013/10 Vicente J. Botet Escriba
+// Creation.
+
+#ifndef BOOST_CSBL_TUPLE_HPP
+#define BOOST_CSBL_TUPLE_HPP
+
+#include <boost/config.hpp>
+
+#if defined BOOST_THREAD_USES_BOOST_TUPLE || defined BOOST_NO_CXX11_HDR_TUPLE || defined BOOST_NO_CXX11_RVALUE_REFERENCES
+#include <boost/tuple/tuple.hpp>
+#ifndef BOOST_THREAD_USES_BOOST_TUPLE
+#define BOOST_THREAD_USES_BOOST_TUPLE
+#endif
+
+#else
+#include <tuple>
+#endif
+
+namespace boost
+{
+ namespace csbl
+ {
+#if defined BOOST_THREAD_USES_BOOST_TUPLE
+ using ::boost::tuple;
+ using ::boost::get;
+ using ::boost::make_tuple;
+ //using ::boost::tuple_size;
+#else
+ // 20.4.2, class template tuple:
+ using ::std::tuple;
+ using ::std::get;
+ using ::std::make_tuple;
+ using ::std::tuple_size;
+ // 20.4.2.4, tuple creation functions:
+ // 20.4.2.5, tuple helper classes:
+ // 20.4.2.6, element access:
+ // 20.4.2.7, relational operators:
+ // 20.4.2.8, allocator-related traits
+ // 20.4.2.9, specialized algorithms:
+#endif
+
+ }
+}
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/csbl/vector.hpp b/src/third_party/boost-1.60.0/boost/thread/csbl/vector.hpp
new file mode 100644
index 00000000000..c77a5b143bb
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/csbl/vector.hpp
@@ -0,0 +1,35 @@
+// 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)
+//
+// 2013/10 Vicente J. Botet Escriba
+// Creation.
+
+#ifndef BOOST_CSBL_VECTOR_HPP
+#define BOOST_CSBL_VECTOR_HPP
+
+#include <boost/config.hpp>
+
+#if defined BOOST_THREAD_USES_BOOST_VECTOR || defined BOOST_NO_CXX11_RVALUE_REFERENCES || defined BOOST_MSVC
+#ifndef BOOST_THREAD_USES_BOOST_VECTOR
+#define BOOST_THREAD_USES_BOOST_VECTOR
+#endif
+#include <boost/container/vector.hpp>
+#else
+#include <vector>
+#endif
+
+namespace boost
+{
+ namespace csbl
+ {
+#if defined BOOST_THREAD_USES_BOOST_VECTOR
+ using ::boost::container::vector;
+#else
+ using ::std::vector;
+#endif
+
+ }
+}
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/cv_status.hpp b/src/third_party/boost-1.60.0/boost/thread/cv_status.hpp
new file mode 100644
index 00000000000..e52de4a5220
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/cv_status.hpp
@@ -0,0 +1,26 @@
+// cv_status.hpp
+//
+// 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_CV_STATUS_HPP
+#define BOOST_THREAD_CV_STATUS_HPP
+
+#include <boost/core/scoped_enum.hpp>
+
+namespace boost
+{
+
+ // enum class cv_status;
+ BOOST_SCOPED_ENUM_DECLARE_BEGIN(cv_status)
+ {
+ no_timeout,
+ timeout
+ }
+ BOOST_SCOPED_ENUM_DECLARE_END(cv_status)
+}
+
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/detail/config.hpp b/src/third_party/boost-1.60.0/boost/thread/detail/config.hpp
new file mode 100644
index 00000000000..475dadbaaa0
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/detail/config.hpp
@@ -0,0 +1,465 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+// Copyright (C) 2011-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)
+
+#ifndef BOOST_THREAD_CONFIG_WEK01032003_HPP
+#define BOOST_THREAD_CONFIG_WEK01032003_HPP
+
+#include <boost/config.hpp>
+#include <boost/detail/workaround.hpp>
+#include <boost/thread/detail/platform.hpp>
+
+//#define BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS
+// ATTRIBUTE_MAY_ALIAS
+
+#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
+
+ // GCC since 3.3 has may_alias attribute that helps to alleviate optimizer issues with
+ // regard to violation of the strict aliasing rules.
+
+ #define BOOST_THREAD_DETAIL_USE_ATTRIBUTE_MAY_ALIAS
+ #define BOOST_THREAD_ATTRIBUTE_MAY_ALIAS __attribute__((__may_alias__))
+#else
+ #define BOOST_THREAD_ATTRIBUTE_MAY_ALIAS
+#endif
+
+
+#if defined BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED
+#define BOOST_THREAD_ASSERT_PRECONDITION(EXPR, EX) \
+ if (EXPR) {} else boost::throw_exception(EX)
+#define BOOST_THREAD_VERIFY_PRECONDITION(EXPR, EX) \
+ if (EXPR) {} else boost::throw_exception(EX)
+#define BOOST_THREAD_THROW_ELSE_RETURN(EX, RET) \
+ boost::throw_exception(EX)
+#else
+#define BOOST_THREAD_ASSERT_PRECONDITION(EXPR, EX)
+#define BOOST_THREAD_VERIFY_PRECONDITION(EXPR, EX) \
+ (void)(EXPR)
+#define BOOST_THREAD_THROW_ELSE_RETURN(EX, RET) \
+ return (RET)
+#endif
+
+// This compiler doesn't support Boost.Chrono
+#if defined __IBMCPP__ && (__IBMCPP__ < 1100) \
+ && ! defined BOOST_THREAD_DONT_USE_CHRONO
+#define BOOST_THREAD_DONT_USE_CHRONO
+#if ! defined BOOST_THREAD_USES_DATETIME
+#define BOOST_THREAD_USES_DATETIME
+#endif
+#endif
+
+// This compiler doesn't support Boost.Move
+#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100) \
+ && ! defined BOOST_THREAD_DONT_USE_MOVE
+#define BOOST_THREAD_DONT_USE_MOVE
+#endif
+
+// This compiler doesn't support Boost.Container Allocators files
+#if defined __SUNPRO_CC \
+ && ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS
+#define BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS
+#endif
+
+#if defined _WIN32_WCE && _WIN32_WCE==0x501 \
+ && ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS
+#define BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS
+#endif
+
+
+#if defined BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX || defined BOOST_NO_CXX11_HDR_INITIALIZER_LIST
+#define BOOST_THREAD_NO_CXX11_HDR_INITIALIZER_LIST
+#define BOOST_THREAD_NO_MAKE_LOCK_GUARD
+#define BOOST_THREAD_NO_MAKE_STRICT_LOCK
+#define BOOST_THREAD_NO_MAKE_NESTED_STRICT_LOCK
+#endif
+
+#if defined(BOOST_NO_CXX11_HDR_TUPLE) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+#define BOOST_THREAD_NO_MAKE_UNIQUE_LOCKS
+#define BOOST_THREAD_NO_SYNCHRONIZE
+#elif defined _MSC_VER && _MSC_VER <= 1600
+// C++ features supported by VC++ 10 (aka 2010)
+#define BOOST_THREAD_NO_MAKE_UNIQUE_LOCKS
+#define BOOST_THREAD_NO_SYNCHRONIZE
+#endif
+
+/// BASIC_THREAD_ID
+#if ! defined BOOST_THREAD_DONT_PROVIDE_BASIC_THREAD_ID \
+ && ! defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
+#define BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
+#endif
+
+/// RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
+//#if defined BOOST_NO_CXX11_RVALUE_REFERENCES || defined BOOST_MSVC
+#define BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
+//#endif
+
+// Default version
+#if !defined BOOST_THREAD_VERSION
+#define BOOST_THREAD_VERSION 2
+#else
+#if BOOST_THREAD_VERSION!=2 && BOOST_THREAD_VERSION!=3 && BOOST_THREAD_VERSION!=4
+#error "BOOST_THREAD_VERSION must be 2, 3 or 4"
+#endif
+#endif
+
+// CHRONO
+// Uses Boost.Chrono by default if not stated the opposite defining BOOST_THREAD_DONT_USE_CHRONO
+#if ! defined BOOST_THREAD_DONT_USE_CHRONO \
+ && ! defined BOOST_THREAD_USES_CHRONO
+#define BOOST_THREAD_USES_CHRONO
+#endif
+
+#if ! defined BOOST_THREAD_DONT_USE_ATOMIC \
+ && ! defined BOOST_THREAD_USES_ATOMIC
+#define BOOST_THREAD_USES_ATOMIC
+//#define BOOST_THREAD_DONT_USE_ATOMIC
+#endif
+
+#if defined BOOST_THREAD_USES_ATOMIC
+// Andrey Semashev
+#define BOOST_THREAD_ONCE_ATOMIC
+#else
+//#elif ! defined BOOST_NO_CXX11_THREAD_LOCAL && ! defined BOOST_NO_THREAD_LOCAL && ! defined BOOST_THREAD_NO_UINT32_PSEUDO_ATOMIC
+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2444.html#Appendix
+#define BOOST_THREAD_ONCE_FAST_EPOCH
+#endif
+#if BOOST_THREAD_VERSION==2
+
+// PROVIDE_PROMISE_LAZY
+#if ! defined BOOST_THREAD_DONT_PROVIDE_PROMISE_LAZY \
+ && ! defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
+#define BOOST_THREAD_PROVIDES_PROMISE_LAZY
+#endif
+
+// PROVIDE_THREAD_EQ
+#if ! defined BOOST_THREAD_DONT_PROVIDE_THREAD_EQ \
+ && ! defined BOOST_THREAD_PROVIDES_THREAD_EQ
+#define BOOST_THREAD_PROVIDES_THREAD_EQ
+#endif
+
+#endif
+
+#if BOOST_THREAD_VERSION>=3
+
+// ONCE_CXX11
+// fixme BOOST_THREAD_PROVIDES_ONCE_CXX11 doesn't works when thread.cpp is compiled BOOST_THREAD_VERSION 3
+#if ! defined BOOST_THREAD_DONT_PROVIDE_ONCE_CXX11 \
+ && ! defined BOOST_THREAD_PROVIDES_ONCE_CXX11
+#define BOOST_THREAD_DONT_PROVIDE_ONCE_CXX11
+#endif
+
+// THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE
+#if ! defined BOOST_THREAD_DONT_PROVIDE_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE \
+ && ! defined BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE
+#define BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE
+#endif
+
+// THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE
+#if ! defined BOOST_THREAD_DONT_PROVIDE_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE \
+ && ! defined BOOST_THREAD_PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE
+#define BOOST_THREAD_PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE
+#endif
+
+// PROVIDE_FUTURE
+#if ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE \
+ && ! defined BOOST_THREAD_PROVIDES_FUTURE
+#define BOOST_THREAD_PROVIDES_FUTURE
+#endif
+
+// FUTURE_CTOR_ALLOCATORS
+#if ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS \
+ && ! defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+#define BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+#endif
+
+// SHARED_MUTEX_UPWARDS_CONVERSIONS
+#if ! defined BOOST_THREAD_DONT_PROVIDE_SHARED_MUTEX_UPWARDS_CONVERSIONS \
+ && ! defined BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+#define BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+#endif
+
+// PROVIDE_EXPLICIT_LOCK_CONVERSION
+#if ! defined BOOST_THREAD_DONT_PROVIDE_EXPLICIT_LOCK_CONVERSION \
+ && ! defined BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
+#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
+#endif
+
+// GENERIC_SHARED_MUTEX_ON_WIN
+#if ! defined BOOST_THREAD_DONT_PROVIDE_GENERIC_SHARED_MUTEX_ON_WIN \
+ && ! defined BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+#endif
+
+// USE_MOVE
+#if ! defined BOOST_THREAD_DONT_USE_MOVE \
+ && ! defined BOOST_THREAD_USES_MOVE
+#define BOOST_THREAD_USES_MOVE
+#endif
+
+#endif
+
+// deprecated since version 4
+#if BOOST_THREAD_VERSION < 4
+
+// NESTED_LOCKS
+#if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS \
+ && ! defined BOOST_THREAD_DONT_PROVIDE_NESTED_LOCKS
+#define BOOST_THREAD_PROVIDES_NESTED_LOCKS
+#endif
+
+// CONDITION
+#if ! defined BOOST_THREAD_PROVIDES_CONDITION \
+ && ! defined BOOST_THREAD_DONT_PROVIDE_CONDITION
+#define BOOST_THREAD_PROVIDES_CONDITION
+#endif
+
+// USE_DATETIME
+#if ! defined BOOST_THREAD_DONT_USE_DATETIME \
+ && ! defined BOOST_THREAD_USES_DATETIME
+#define BOOST_THREAD_USES_DATETIME
+#endif
+#endif
+
+#if BOOST_THREAD_VERSION>=4
+
+// SIGNATURE_PACKAGED_TASK
+#if ! defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK \
+ && ! defined BOOST_THREAD_DONT_PROVIDE_SIGNATURE_PACKAGED_TASK
+#define BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+#endif
+
+// VARIADIC_THREAD
+#if ! defined BOOST_THREAD_PROVIDES_VARIADIC_THREAD \
+ && ! defined BOOST_THREAD_DONT_PROVIDE_VARIADIC_THREAD
+
+#if ! defined(BOOST_NO_SFINAE_EXPR) && \
+ ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
+ ! defined(BOOST_NO_CXX11_DECLTYPE) && \
+ ! defined(BOOST_NO_CXX11_DECLTYPE_N3276) && \
+ ! defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES) && \
+ ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
+ ! defined(BOOST_NO_CXX11_HDR_TUPLE)
+
+#define BOOST_THREAD_PROVIDES_VARIADIC_THREAD
+#endif
+#endif
+
+#if ! defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY \
+ && ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE_WHEN_ALL_WHEN_ANY
+
+#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
+ ! defined(BOOST_NO_CXX11_HDR_TUPLE)
+
+#define BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
+#endif
+#endif
+
+// ! defined(BOOST_NO_SFINAE_EXPR) &&
+// ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES) &&
+// ! defined(BOOST_NO_CXX11_AUTO) &&
+// ! defined(BOOST_NO_CXX11_DECLTYPE) &&
+// ! defined(BOOST_NO_CXX11_DECLTYPE_N3276) &&
+
+
+// MAKE_READY_AT_THREAD_EXIT
+#if ! defined BOOST_THREAD_PROVIDES_MAKE_READY_AT_THREAD_EXIT \
+ && ! defined BOOST_THREAD_DONT_PROVIDE_MAKE_READY_AT_THREAD_EXIT
+
+//#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+#define BOOST_THREAD_PROVIDES_MAKE_READY_AT_THREAD_EXIT
+//#endif
+#endif
+
+// FUTURE_CONTINUATION
+#if ! defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION \
+ && ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE_CONTINUATION
+#define BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
+#endif
+
+#if ! defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP \
+ && ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE_UNWRAP
+#define BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
+#endif
+
+// FUTURE_INVALID_AFTER_GET
+#if ! defined BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET \
+ && ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE_INVALID_AFTER_GET
+#define BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
+#endif
+
+// NESTED_LOCKS
+#if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS \
+ && ! defined BOOST_THREAD_DONT_PROVIDE_NESTED_LOCKS
+#define BOOST_THREAD_DONT_PROVIDE_NESTED_LOCKS
+#endif
+
+// CONDITION
+#if ! defined BOOST_THREAD_PROVIDES_CONDITION \
+ && ! defined BOOST_THREAD_DONT_PROVIDE_CONDITION
+#define BOOST_THREAD_DONT_PROVIDE_CONDITION
+#endif
+
+#endif // BOOST_THREAD_VERSION>=4
+
+// INTERRUPTIONS
+#if ! defined BOOST_THREAD_PROVIDES_INTERRUPTIONS \
+ && ! defined BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS
+#define BOOST_THREAD_PROVIDES_INTERRUPTIONS
+#endif
+
+// CORRELATIONS
+
+// EXPLICIT_LOCK_CONVERSION.
+#if defined BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
+#define BOOST_THREAD_EXPLICIT_LOCK_CONVERSION explicit
+#else
+#define BOOST_THREAD_EXPLICIT_LOCK_CONVERSION
+#endif
+
+// BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN is defined if BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+#if defined BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS \
+&& ! defined BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+#endif
+
+// For C++11 call_once interface the compiler MUST support constexpr.
+// Otherwise once_flag would be initialized during dynamic initialization stage, which is not thread-safe.
+#if defined(BOOST_THREAD_PROVIDES_ONCE_CXX11)
+#if defined(BOOST_NO_CXX11_CONSTEXPR)
+#undef BOOST_THREAD_PROVIDES_ONCE_CXX11
+#endif
+#endif
+
+#if defined(BOOST_THREAD_PLATFORM_WIN32) && defined BOOST_THREAD_DONT_USE_DATETIME
+#undef BOOST_THREAD_DONT_USE_DATETIME
+#define BOOST_THREAD_USES_DATETIME
+#endif
+
+#if defined(BOOST_THREAD_PLATFORM_WIN32) && defined BOOST_THREAD_DONT_USE_CHRONO
+#undef BOOST_THREAD_DONT_USE_CHRONO
+#define BOOST_THREAD_USES_CHRONO
+#endif
+
+// BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 defined by default up to Boost 1.55
+// BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0 defined by default up to Boost 1.55
+#if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
+
+#if ! defined BOOST_THREAD_PROVIDES_THREAD_EQ
+#define BOOST_THREAD_PROVIDES_THREAD_EQ
+#endif
+
+#endif
+
+
+//#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES || defined BOOST_THREAD_USES_MOVE
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+#define BOOST_THREAD_FUTURE_USES_OPTIONAL
+#endif
+
+#if BOOST_WORKAROUND(__BORLANDC__, < 0x600)
+# pragma warn -8008 // Condition always true/false
+# pragma warn -8080 // Identifier declared but never used
+# pragma warn -8057 // Parameter never used
+# pragma warn -8066 // Unreachable code
+#endif
+
+#include <boost/thread/detail/platform.hpp>
+
+#if defined(BOOST_THREAD_PLATFORM_WIN32)
+#else
+ # if defined(BOOST_HAS_PTHREAD_DELAY_NP) || defined(BOOST_HAS_NANOSLEEP)
+ # define BOOST_THREAD_SLEEP_FOR_IS_STEADY
+ # endif
+#endif
+
+// provided for backwards compatibility, since this
+// macro was used for several releases by mistake.
+#if defined(BOOST_THREAD_DYN_DLL) && ! defined BOOST_THREAD_DYN_LINK
+# define BOOST_THREAD_DYN_LINK
+#endif
+
+// compatibility with the rest of Boost's auto-linking code:
+#if defined(BOOST_THREAD_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)
+# undef BOOST_THREAD_USE_LIB
+# if !defined(BOOST_THREAD_USE_DLL)
+# define BOOST_THREAD_USE_DLL
+# endif
+#endif
+
+#if defined(BOOST_THREAD_BUILD_DLL) //Build dll
+#elif defined(BOOST_THREAD_BUILD_LIB) //Build lib
+#elif defined(BOOST_THREAD_USE_DLL) //Use dll
+#elif defined(BOOST_THREAD_USE_LIB) //Use lib
+#else //Use default
+# if defined(BOOST_THREAD_PLATFORM_WIN32)
+# if defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN) \
+ || defined(__MINGW32__) || defined(MINGW32) || defined(BOOST_MINGW32)
+ //For compilers supporting auto-tss cleanup
+ //with Boost.Threads lib, use Boost.Threads lib
+# define BOOST_THREAD_USE_LIB
+# else
+ //For compilers not yet supporting auto-tss cleanup
+ //with Boost.Threads lib, use Boost.Threads dll
+# define BOOST_THREAD_USE_DLL
+# endif
+# else
+# define BOOST_THREAD_USE_LIB
+# endif
+#endif
+
+#if defined(BOOST_HAS_DECLSPEC)
+# if defined(BOOST_THREAD_BUILD_DLL) //Build dll
+# define BOOST_THREAD_DECL BOOST_SYMBOL_EXPORT
+//# define BOOST_THREAD_DECL __declspec(dllexport)
+
+# elif defined(BOOST_THREAD_USE_DLL) //Use dll
+# define BOOST_THREAD_DECL BOOST_SYMBOL_IMPORT
+//# define BOOST_THREAD_DECL __declspec(dllimport)
+# else
+# define BOOST_THREAD_DECL
+# endif
+#elif (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
+# define BOOST_THREAD_DECL BOOST_SYMBOL_VISIBLE
+
+#else
+# define BOOST_THREAD_DECL
+#endif // BOOST_HAS_DECLSPEC
+
+//
+// Automatically link to the correct build variant where possible.
+//
+#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_THREAD_NO_LIB) && !defined(BOOST_THREAD_BUILD_DLL) && !defined(BOOST_THREAD_BUILD_LIB)
+//
+// Tell the autolink to link dynamically, this will get undef'ed by auto_link.hpp
+// once it's done with it:
+//
+#if defined(BOOST_THREAD_USE_DLL)
+# define BOOST_DYN_LINK
+#endif
+//
+// Set the name of our library, this will get undef'ed by auto_link.hpp
+// once it's done with it:
+//
+#if defined(BOOST_THREAD_LIB_NAME)
+# define BOOST_LIB_NAME BOOST_THREAD_LIB_NAME
+#else
+# define BOOST_LIB_NAME boost_thread
+#endif
+//
+// If we're importing code from a dll, then tell auto_link.hpp about it:
+//
+// And include the header that does the work:
+//
+#include <boost/config/auto_link.hpp>
+#endif // auto-linking disabled
+
+#endif // BOOST_THREAD_CONFIG_WEK1032003_HPP
+
+// Change Log:
+// 22 Jan 05 Roland Schwarz (speedsnail)
+// Usage of BOOST_HAS_DECLSPEC macro.
+// Default again is static lib usage.
+// BOOST_DYN_LINK only defined when autolink included.
diff --git a/src/third_party/boost-1.60.0/boost/thread/detail/counter.hpp b/src/third_party/boost-1.60.0/boost/thread/detail/counter.hpp
new file mode 100644
index 00000000000..38e1597c574
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/detail/counter.hpp
@@ -0,0 +1,106 @@
+// Distributed under the 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
+
+#ifndef BOOST_THREAD_COUNTER_HPP
+#define BOOST_THREAD_COUNTER_HPP
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/detail/delete.hpp>
+
+//#include <boost/thread/mutex.hpp>
+//#include <boost/thread/lock_types.hpp>
+#include <boost/thread/condition_variable.hpp>
+#include <boost/chrono/duration.hpp>
+#include <boost/chrono/time_point.hpp>
+#include <boost/assert.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ namespace detail {
+ struct counter
+ {
+ condition_variable cond_;
+ std::size_t value_;
+
+ counter(std::size_t value)
+ : value_(value)
+ {
+
+ }
+ counter& operator=(counter const& rhs)
+ {
+ value_ = rhs.value_;
+ return *this;
+ }
+ counter& operator=(std::size_t value)
+ {
+ value_ = value;
+ return *this;
+ }
+
+ operator std::size_t() const
+ {
+ return value_;
+ }
+ operator std::size_t&()
+ {
+ return value_;
+ }
+
+ void inc_and_notify_all()
+ {
+ ++value_;
+ cond_.notify_all();
+ }
+
+ void dec_and_notify_all()
+ {
+ --value_;
+ cond_.notify_all();
+ }
+ void assign_and_notify_all(counter const& rhs)
+ {
+ value_ = rhs.value_;
+ cond_.notify_all();
+ }
+ void assign_and_notify_all(std::size_t value)
+ {
+ value_ = value;
+ cond_.notify_all();
+ }
+ };
+ struct counter_is_not_zero
+ {
+ counter_is_not_zero(counter const& count) : count_(count) {}
+ bool operator()() const { return count_ != 0; }
+ counter const& count_;
+ };
+ struct counter_is_zero
+ {
+ counter_is_zero(counter const& count) : count_(count) {}
+ bool operator()() const { return count_ == 0; }
+ counter const& count_;
+ };
+ struct is_zero
+ {
+ is_zero(std::size_t& count) : count_(count) {}
+ bool operator()() const { return count_ == 0; }
+ std::size_t& count_;
+ };
+ struct not_equal
+ {
+ not_equal(std::size_t& x, std::size_t& y) : x_(x), y_(y) {}
+ bool operator()() const { return x_ != y_; }
+ std::size_t& x_;
+ std::size_t& y_;
+ };
+ }
+} // namespace boost
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/detail/delete.hpp b/src/third_party/boost-1.60.0/boost/thread/detail/delete.hpp
new file mode 100644
index 00000000000..8f8113f4e87
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/detail/delete.hpp
@@ -0,0 +1,58 @@
+// 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)
+
+#ifndef BOOST_THREAD_DETAIL_DELETE_HPP
+#define BOOST_THREAD_DETAIL_DELETE_HPP
+
+#include <boost/config.hpp>
+
+/**
+ * BOOST_THREAD_DELETE_COPY_CTOR deletes the copy constructor when the compiler supports it or
+ * makes it private.
+ *
+ * BOOST_THREAD_DELETE_COPY_ASSIGN deletes the copy assignment when the compiler supports it or
+ * makes it private.
+ */
+
+#if ! defined BOOST_NO_CXX11_DELETED_FUNCTIONS && ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+#define BOOST_THREAD_DELETE_COPY_CTOR(CLASS) \
+ CLASS(CLASS const&) = delete; \
+
+#define BOOST_THREAD_DELETE_COPY_ASSIGN(CLASS) \
+ CLASS& operator=(CLASS const&) = delete;
+
+#else // BOOST_NO_CXX11_DELETED_FUNCTIONS
+#if defined(BOOST_MSVC) && _MSC_VER >= 1600
+#define BOOST_THREAD_DELETE_COPY_CTOR(CLASS) \
+ private: \
+ CLASS(CLASS const&); \
+ public:
+
+#define BOOST_THREAD_DELETE_COPY_ASSIGN(CLASS) \
+ private: \
+ CLASS& operator=(CLASS const&); \
+ public:
+#else
+#define BOOST_THREAD_DELETE_COPY_CTOR(CLASS) \
+ private: \
+ CLASS(CLASS&); \
+ public:
+
+#define BOOST_THREAD_DELETE_COPY_ASSIGN(CLASS) \
+ private: \
+ CLASS& operator=(CLASS&); \
+ public:
+#endif
+#endif // BOOST_NO_CXX11_DELETED_FUNCTIONS
+
+/**
+ * BOOST_THREAD_NO_COPYABLE deletes the copy constructor and assignment when the compiler supports it or
+ * makes them private.
+ */
+#define BOOST_THREAD_NO_COPYABLE(CLASS) \
+ BOOST_THREAD_DELETE_COPY_CTOR(CLASS) \
+ BOOST_THREAD_DELETE_COPY_ASSIGN(CLASS)
+
+#endif // BOOST_THREAD_DETAIL_DELETE_HPP
diff --git a/src/third_party/boost-1.60.0/boost/thread/detail/force_cast.hpp b/src/third_party/boost-1.60.0/boost/thread/detail/force_cast.hpp
new file mode 100644
index 00000000000..d5d15adc1a7
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/detail/force_cast.hpp
@@ -0,0 +1,39 @@
+// Copyright (C) 2001-2003
+// Mac Murrett
+//
+// Distributed under the 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 http://www.boost.org for most recent version including documentation.
+
+#ifndef BOOST_FORCE_CAST_MJM012402_HPP
+#define BOOST_FORCE_CAST_MJM012402_HPP
+
+#include <boost/thread/detail/config.hpp>
+
+namespace boost {
+namespace detail {
+namespace thread {
+
+// force_cast will convert anything to anything.
+
+// general case
+template<class Return_Type, class Argument_Type>
+inline Return_Type &force_cast(Argument_Type &rSrc)
+{
+ return(*reinterpret_cast<Return_Type *>(&rSrc));
+}
+
+// specialization for const
+template<class Return_Type, class Argument_Type>
+inline const Return_Type &force_cast(const Argument_Type &rSrc)
+{
+ return(*reinterpret_cast<const Return_Type *>(&rSrc));
+}
+
+} // namespace thread
+} // namespace detail
+} // namespace boost
+
+#endif // BOOST_FORCE_CAST_MJM012402_HPP
diff --git a/src/third_party/boost-1.60.0/boost/thread/detail/function_wrapper.hpp b/src/third_party/boost-1.60.0/boost/thread/detail/function_wrapper.hpp
new file mode 100644
index 00000000000..355f726762b
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/detail/function_wrapper.hpp
@@ -0,0 +1,93 @@
+// 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)
+//
+// 2013/09 Vicente J. Botet Escriba
+// Adapt to boost from CCIA C++11 implementation
+// Make use of Boost.Move
+
+#ifndef BOOST_THREAD_DETAIL_FUNCTION_WRAPPER_HPP
+#define BOOST_THREAD_DETAIL_FUNCTION_WRAPPER_HPP
+
+#include <boost/config.hpp>
+#include <boost/thread/detail/memory.hpp>
+#include <boost/thread/detail/move.hpp>
+
+#include <boost/thread/csbl/memory/unique_ptr.hpp>
+
+#include <memory>
+#include <functional>
+
+namespace boost
+{
+ namespace detail
+ {
+ class function_wrapper
+ {
+ struct impl_base
+ {
+ virtual void call()=0;
+ virtual ~impl_base()
+ {
+ }
+ };
+ typedef boost::csbl::unique_ptr<impl_base> impl_base_type;
+ impl_base_type impl;
+ template <typename F>
+ struct impl_type: impl_base
+ {
+ F f;
+ impl_type(F const &f_)
+ : f(f_)
+ {}
+ impl_type(BOOST_THREAD_RV_REF(F) f_)
+ : f(boost::move(f_))
+ {}
+
+ void call()
+ {
+ if (impl) f();
+ }
+ };
+ public:
+ BOOST_THREAD_MOVABLE_ONLY(function_wrapper)
+
+//#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ template<typename F>
+ function_wrapper(F const& f):
+ impl(new impl_type<F>(f))
+ {}
+//#endif
+ template<typename F>
+ function_wrapper(BOOST_THREAD_RV_REF(F) f):
+ impl(new impl_type<F>(boost::forward<F>(f)))
+ {}
+ function_wrapper(BOOST_THREAD_RV_REF(function_wrapper) other) BOOST_NOEXCEPT :
+ impl(other.impl)
+ {
+ other.impl = 0;
+ }
+ function_wrapper()
+ : impl(0)
+ {
+ }
+ ~function_wrapper()
+ {
+ }
+
+ function_wrapper& operator=(BOOST_THREAD_RV_REF(function_wrapper) other) BOOST_NOEXCEPT
+ {
+ impl=other.impl;
+ other.impl=0;
+ return *this;
+ }
+
+ void operator()()
+ { impl->call();}
+
+ };
+ }
+}
+
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/detail/invoke.hpp b/src/third_party/boost-1.60.0/boost/thread/detail/invoke.hpp
new file mode 100644
index 00000000000..e772da29ee9
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/detail/invoke.hpp
@@ -0,0 +1,1604 @@
+// Copyright (C) 2012-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)
+
+// 2013/04 Vicente J. Botet Escriba
+// Provide implementation up to 9 parameters when BOOST_NO_CXX11_VARIADIC_TEMPLATES is defined.
+// Make use of Boost.Move
+// Make use of Boost.Tuple (movable)
+// 2012 Vicente J. Botet Escriba
+// Provide implementation _RET using bind when BOOST_NO_CXX11_HDR_FUNCTIONAL and BOOST_NO_SFINAE_EXPR are not defined
+// 2012 Vicente J. Botet Escriba
+// Adapt to boost libc++ implementation
+
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+// The invoke code is based on the one from libcxx.
+//===----------------------------------------------------------------------===//
+
+#ifndef BOOST_THREAD_DETAIL_INVOKE_HPP
+#define BOOST_THREAD_DETAIL_INVOKE_HPP
+
+#include <boost/config.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/core/enable_if.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/type_traits/is_base_of.hpp>
+#include <boost/type_traits/is_pointer.hpp>
+#include <boost/type_traits/is_member_function_pointer.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL
+#include <functional>
+#endif
+
+namespace boost
+{
+ namespace detail
+ {
+
+
+#if ! defined(BOOST_NO_SFINAE_EXPR) && \
+ ! defined(BOOST_NO_CXX11_DECLTYPE) && \
+ ! defined(BOOST_NO_CXX11_DECLTYPE_N3276) && \
+ ! defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES)
+
+#define BOOST_THREAD_PROVIDES_INVOKE
+
+#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ // bullets 1 and 2
+
+ template <class Fp, class A0, class ...Args>
+ inline auto
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args)
+ -> decltype((boost::forward<A0>(a0).*f)(boost::forward<Args>(args)...))
+ {
+ return (boost::forward<A0>(a0).*f)(boost::forward<Args>(args)...);
+ }
+ template <class R, class Fp, class A0, class ...Args>
+ inline auto
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args)
+ -> decltype((boost::forward<A0>(a0).*f)(boost::forward<Args>(args)...))
+ {
+ return (boost::forward<A0>(a0).*f)(boost::forward<Args>(args)...);
+ }
+
+ template <class Fp, class A0, class ...Args>
+ inline auto
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args)
+ -> decltype(((*boost::forward<A0>(a0)).*f)(boost::forward<Args>(args)...))
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<Args>(args)...);
+ }
+ template <class R, class Fp, class A0, class ...Args>
+ inline auto
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args)
+ -> decltype(((*boost::forward<A0>(a0)).*f)(boost::forward<Args>(args)...))
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<Args>(args)...);
+ }
+
+ // bullets 3 and 4
+
+ template <class Fp, class A0>
+ inline auto
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0)
+ -> decltype(boost::forward<A0>(a0).*f)
+ {
+ return boost::forward<A0>(a0).*f;
+ }
+
+ template <class Fp, class A0>
+ inline auto
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0)
+ -> decltype((*boost::forward<A0>(a0)).*f)
+ {
+ return (*boost::forward<A0>(a0)).*f;
+ }
+
+ template <class R, class Fp, class A0>
+ inline auto
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0)
+ -> decltype(boost::forward<A0>(a0).*f)
+ {
+ return boost::forward<A0>(a0).*f;
+ }
+
+ template <class R, class Fp, class A0>
+ inline auto
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0)
+ -> decltype((*boost::forward<A0>(a0)).*f)
+ {
+ return (*boost::forward<A0>(a0)).*f;
+ }
+
+
+ // bullet 5
+
+ template <class R, class Fp, class ...Args>
+ inline auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(Args) ...args)
+ -> decltype(boost::forward<Fp>(f)(boost::forward<Args>(args)...))
+ {
+ return boost::forward<Fp>(f)(boost::forward<Args>(args)...);
+ }
+ template <class Fp, class ...Args>
+ inline auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(Args) ...args)
+ -> decltype(boost::forward<Fp>(f)(boost::forward<Args>(args)...))
+ {
+ return boost::forward<Fp>(f)(boost::forward<Args>(args)...);
+ }
+
+#else // BOOST_NO_CXX11_VARIADIC_TEMPLATES
+
+ // bullets 1 and 2
+
+ template <class Fp, class A0>
+ inline
+ auto
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0)
+ -> decltype((boost::forward<A0>(a0).*f)())
+ {
+ return (boost::forward<A0>(a0).*f)();
+ }
+ template <class R, class Fp, class A0>
+ inline
+ auto
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0)
+ -> decltype((boost::forward<A0>(a0).*f)())
+ {
+ return (boost::forward<A0>(a0).*f)();
+ }
+ template <class Fp, class A0, class A1>
+ inline
+ auto
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1)
+ -> decltype((boost::forward<A0>(a0).*f)(boost::forward<A1>(a1)))
+ {
+ return (boost::forward<A0>(a0).*f)(boost::forward<A1>(a1));
+ }
+ template <class R, class Fp, class A0, class A1>
+ inline
+ auto
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1)
+ -> decltype((boost::forward<A0>(a0).*f)(boost::forward<A1>(a1)))
+ {
+ return (boost::forward<A0>(a0).*f)(boost::forward<A1>(a1));
+ }
+ template <class Fp, class A0, class A1, class A2>
+ inline
+ auto
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
+ -> decltype((boost::forward<A0>(a0).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2)))
+ {
+ return (boost::forward<A0>(a0).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
+ }
+ template <class R, class Fp, class A0, class A1, class A2>
+ inline
+ auto
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
+ -> decltype((boost::forward<A0>(a0).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2)))
+ {
+ return (boost::forward<A0>(a0).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
+ }
+
+ template <class Fp, class A0>
+ inline
+ auto
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0)
+ -> decltype(((*boost::forward<A0>(a0)).*f)())
+ {
+ return ((*boost::forward<A0>(a0)).*f)();
+ }
+ template <class R, class Fp, class A0>
+ inline
+ auto
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0)
+ -> decltype(((*boost::forward<A0>(a0)).*f)())
+ {
+ return ((*boost::forward<A0>(a0)).*f)();
+ }
+ template <class Fp, class A0, class A1>
+ inline
+ auto
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1)
+ -> decltype(((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1)))
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1));
+ }
+ template <class R, class Fp, class A0, class A1>
+ inline
+ auto
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1)
+ -> decltype(((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1)))
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1));
+ }
+ template <class Fp, class A0, class A1, class A2>
+ inline
+ auto
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
+ -> decltype(((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2)))
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
+ }
+ template <class R, class Fp, class A0, class A1, class A2>
+ inline
+ auto
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
+ -> decltype(((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2)))
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
+ }
+
+ // bullets 3 and 4
+
+ template <class Fp, class A0>
+ inline
+ auto
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0)
+ -> decltype(boost::forward<A0>(a0).*f)
+ {
+ return boost::forward<A0>(a0).*f;
+ }
+ template <class R, class Fp, class A0>
+ inline
+ auto
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0)
+ -> decltype(boost::forward<A0>(a0).*f)
+ {
+ return boost::forward<A0>(a0).*f;
+ }
+
+ template <class Fp, class A0>
+ inline
+ auto
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0)
+ -> decltype((*boost::forward<A0>(a0)).*f)
+ {
+ return (*boost::forward<A0>(a0)).*f;
+ }
+ template <class R, class Fp, class A0>
+ inline
+ auto
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0)
+ -> decltype((*boost::forward<A0>(a0)).*f)
+ {
+ return (*boost::forward<A0>(a0)).*f;
+ }
+
+ // bullet 5
+
+ template <class Fp>
+ inline
+ auto invoke(BOOST_THREAD_RV_REF(Fp) f)
+ -> decltype(boost::forward<Fp>(f)())
+ {
+ return boost::forward<Fp>(f)();
+ }
+ template <class Fp, class A1>
+ inline
+ auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1)
+ -> decltype(boost::forward<Fp>(f)(boost::forward<A1>(a1)))
+ {
+ return boost::forward<Fp>(f)(boost::forward<A1>(a1));
+ } template <class Fp, class A1, class A2>
+ inline
+ auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
+ -> decltype(boost::forward<Fp>(f)(boost::forward<A1>(a1), boost::forward<A2>(a2)))
+ {
+ return boost::forward<Fp>(f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
+ }
+ template <class Fp, class A1, class A2, class A3>
+ inline
+ auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
+ -> decltype(boost::forward<Fp>(f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3)))
+ {
+ return boost::forward<Fp>(f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
+ }
+
+
+ template <class R, class Fp>
+ inline
+ auto invoke(BOOST_THREAD_RV_REF(Fp) f)
+ -> decltype(boost::forward<Fp>(f)())
+ {
+ return boost::forward<Fp>(f)();
+ }
+ template <class R, class Fp, class A1>
+ inline
+ auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1)
+ -> decltype(boost::forward<Fp>(f)(boost::forward<A1>(a1)))
+ {
+ return boost::forward<Fp>(f)(boost::forward<A1>(a1));
+ }
+ template <class R, class Fp, class A1, class A2>
+ inline
+ auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
+ -> decltype(boost::forward<Fp>(f)(boost::forward<A1>(a1), boost::forward<A2>(a2)))
+ {
+ return boost::forward<Fp>(f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
+ }
+ template <class R, class Fp, class A1, class A2, class A3>
+ inline
+ auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
+ -> decltype(boost::forward<Fp>(f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3)))
+ {
+ return boost::forward<Fp>(f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
+ }
+
+#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
+
+#elif ! defined(BOOST_NO_SFINAE_EXPR) && \
+ ! defined BOOST_NO_CXX11_HDR_FUNCTIONAL && \
+ defined BOOST_MSVC
+
+ template <class Ret, class Fp>
+ inline
+ Ret invoke(BOOST_THREAD_RV_REF(Fp) f)
+ {
+ return f();
+ }
+ template <class Ret, class Fp, class A1>
+ inline
+ Ret invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1)
+ {
+ return std::bind(boost::forward<Fp>(f), boost::forward<A1>(a1))();
+ }
+ template <class Ret, class Fp, class A1, class A2>
+ inline
+ Ret invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
+ {
+ return std::bind(boost::forward<Fp>(f), boost::forward<A1>(a1), boost::forward<A2>(a2))();
+ }
+ template <class Ret, class Fp, class A1, class A2, class A3>
+ inline
+ Ret invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
+ {
+ return std::bind(boost::forward<Fp>(f), boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3))();
+ }
+
+#define BOOST_THREAD_PROVIDES_INVOKE_RET
+
+#elif ! defined BOOST_MSVC
+//!!!!! WARNING !!!!! THIS DOESN'T WORKS YET
+#define BOOST_THREAD_PROVIDES_INVOKE_RET
+
+#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+ // bullet 1
+ // (t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is an object of
+ // type T or a reference to an object of type T or a reference to an object of a type derived from T
+ template <class Ret, class A, class A0, class ...Args>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(Args...), BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args)
+ {
+ return (boost::forward<A0>(a0).*f)(boost::forward<Args>(args)...);
+ }
+
+ template <class Ret, class A, class A0, class ...Args>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(Args...) const, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args)
+ {
+ return (boost::forward<A0>(a0).*f)(boost::forward<Args>(args)...);
+ }
+
+ template <class Ret, class A, class A0, class ...Args>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(Args...) volatile, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args)
+ {
+ return (boost::forward<A0>(a0).*f)(boost::forward<Args>(args)...);
+ }
+
+ template <class Ret, class A, class A0, class ...Args>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(Args...) const volatile, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args)
+ {
+ return (boost::forward<A0>(a0).*f)(boost::forward<Args>(args)...);
+ }
+
+ // bullet 2
+ // ((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is not one of
+ // the types described in the previous item;
+ template <class Ret, class A, class A0, class ...Args>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(Args...), BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args)
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<Args>(args)...);
+ }
+
+ template <class Ret, class A, class A0, class ...Args>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(Args...) const, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args)
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<Args>(args)...);
+ }
+
+ template <class Ret, class A, class A0, class ...Args>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(Args...) volatile, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args)
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<Args>(args)...);
+ }
+
+ template <class Ret, class A, class A0, class ...Args>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(Args...) const volatile, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args)
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<Args>(args)...);
+ }
+
+ // bullet 3
+ // t1.*f when N == 1 and f is a pointer to member data of a class T and t1 is an object of type T or a
+ // reference to an object of type T or a reference to an object of a type derived from T;
+// template <class Ret, class A, class A0>
+// inline
+// typename enable_if_c
+// <
+// is_base_of<A, typename remove_reference<A0>::type>::value,
+// typename detail::apply_cv<A0, A>::type&
+// >::type
+// invoke(Ret A::* f, BOOST_THREAD_RV_REF(A0) a0)
+// {
+// return boost::forward<A0>(a0).*f;
+// }
+
+ // bullet 4
+ // (*t1).*f when N == 1 and f is a pointer to member data of a class T and t1 is not one of the types
+ //described in the previous item;
+
+// template <class A0, class Ret, bool>
+// struct d4th_helper
+// {
+// };
+//
+// template <class A0, class Ret>
+// struct d4th_helper<A0, Ret, true>
+// {
+// typedef typename apply_cv<decltype(*declval<A0>()), Ret>::type type;
+// };
+//
+// template <class Ret, class A, class A0>
+// inline
+// typename detail::4th_helper<A, Ret,
+// !is_base_of<A,
+// typename remove_reference<A0>::type
+// >::value
+// >::type&
+// invoke(Ret A::* f, BOOST_THREAD_RV_REF(A0) a0)
+// {
+// return (*boost::forward<A0>(a0)).*f;
+// }
+
+// template <class Ret, class A, class A0>
+// inline
+// typename enable_if_c
+// <
+// !is_base_of<A, typename remove_reference<A0>::type>::value,
+// typename detail::ref_return1<Ret A::*, A0>::type
+// >::type
+// invoke(Ret A::* f, BOOST_THREAD_RV_REF(A0) a0)
+// {
+// return (*boost::forward<A0>(a0)).*f;
+// }
+
+ // bullet 5
+ // f(t1, t2, ..., tN) in all other cases.
+
+ template <class Ret, class Fp, class ...Args>
+ inline Ret do_invoke(mpl::false_, BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(Args) ...args)
+ {
+ return boost::forward<Fp>(f)(boost::forward<Args>(args)...);
+ }
+
+ template <class Ret, class Fp, class ...Args>
+ inline Ret do_invoke(mpl::true_, BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(Args) ...args)
+ {
+ return f(boost::forward<Args>(args)...);
+ }
+
+ template <class Ret, class Fp, class ...Args>
+ inline
+ typename disable_if_c
+ <
+ is_member_function_pointer<Fp>::value,
+ Ret
+ >::type
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(Args) ...args)
+ {
+ return boost::detail::do_invoke<Ret>(boost::is_pointer<Fp>(), boost::forward<Fp>(f), boost::forward<Args>(args)...);
+ }
+#else // BOOST_NO_CXX11_VARIADIC_TEMPLATES
+ // bullet 1
+ // (t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is an object of
+ // type T or a reference to an object of type T or a reference to an object of a type derived from T
+
+ template <class Ret, class A, class A0>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(), A0& a0)
+ {
+ return (a0.*f)();
+ }
+ template <class Ret, class A, class A0>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(), A0* a0)
+ {
+ return ((*a0).*f)();
+ }
+
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1),
+ A0& a0, BOOST_THREAD_RV_REF(A1) a1
+ )
+ {
+ return (a0.*f)(boost::forward<A1>(a1));
+ }
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1), A0& a0, A1 a1)
+ {
+ return (a0.*f)(a1);
+ }
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1), A0* a0, BOOST_THREAD_RV_REF(A1) a1
+ )
+ {
+ return (*(a0).*f)(boost::forward<A1>(a1));
+ }
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1), A0* a0, A1 a1)
+ {
+ return (*a0.*f)(a1);
+ }
+ template <class Ret, class A, class A0, class A1, class A2>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2),
+ A0& a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2
+ )
+ {
+ return (a0.*f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
+ }
+ template <class Ret, class A, class A0, class A1, class A2>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2), A0* a0, A1 a1, A2 a2)
+ {
+ return ((*a0).*f)(a1, a2);
+ }
+ template <class Ret, class A, class A0, class A1, class A2, class A3>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2, A3),
+ A0& a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
+ {
+ return (a0.*f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
+ }
+ template <class Ret, class A, class A0, class A1, class A2, class A3>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2, A3), A0* a0, A1 a1, A2 a2, A3 a3)
+ {
+ return ((*a0).*f)(a1, a2, a3);
+ }
+
+///
+ template <class Ret, class A, class A0>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)() const, A0 const& a0)
+ {
+ return (a0.*f)();
+ }
+ template <class Ret, class A, class A0>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)() const, A0 const* a0)
+ {
+ return ((*a0).*f)();
+ }
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1) const, A0 const& a0, BOOST_THREAD_RV_REF(A1) a1)
+ {
+ return (a0.*f)(boost::forward<A1>(a1));
+ }
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1) const, A0 const* a0, BOOST_THREAD_RV_REF(A1) a1)
+ {
+ return ((*a0).*f)(boost::forward<A1>(a1));
+ }
+
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1) const, A0 const& a0, A1 a1)
+ {
+ return (a0.*f)(a1);
+ }
+ template <class Ret, class A, class A0, class A1, class A2>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2) const,
+ A0 const& a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2
+ )
+ {
+ return (boost::forward<A0>(a0).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2)
+ );
+ }
+ template <class Ret, class A, class A0, class A1, class A2>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2) const, A0 const& a0, A1 a1, A2 a2)
+ {
+ return (a0.*f)(a1, a2);
+ }
+ template <class Ret, class A, class A0, class A1, class A2, class A3>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2, A3) const,
+ BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3
+ )
+ {
+ return (boost::forward<A0>(a0).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
+ }
+ template <class Ret, class A, class A0, class A1, class A2, class A3>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2, A3) const, A0 a0, A1 a1, A2 a2, A3 a3)
+ {
+ return (a0.*f)(a1, a2, a3);
+ }
+ ///
+ template <class Ret, class A, class A0>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)() volatile, BOOST_THREAD_RV_REF(A0) a0)
+ {
+ return (boost::forward<A0>(a0).*f)();
+ }
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1) volatile, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1)
+ {
+ return (boost::forward<A0>(a0).*f)(boost::forward<A1>(a1));
+ }
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1) volatile, A0 a0, A1 a1)
+ {
+ return (a0.*f)(a1);
+ }
+ template <class Ret, class A, class A0, class A1, class A2>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2) volatile,
+ BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
+ {
+ return (boost::forward<A0>(a0).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
+ }
+ template <class Ret, class A, class A0, class A1, class A2>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2) volatile, A0 a0, A1 a1, A2 a2 )
+ {
+ return (a0.*f)(a1, a2);
+ }
+ template <class Ret, class A, class A0, class A1, class A2, class A3>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2, A3) volatile,
+ BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3
+ )
+ {
+ return (boost::forward<A0>(a0).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
+ }
+ template <class Ret, class A, class A0, class A1, class A2, class A3>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2, A3) volatile, A0 a0, A1 a1, A2 a2, A3 a3)
+ {
+ return (a0.*f)(a1, a2, a3);
+ }
+ ///
+ template <class Ret, class A, class A0>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)() const volatile, BOOST_THREAD_RV_REF(A0) a0)
+ {
+ return (boost::forward<A0>(a0).*f)();
+ }
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1) const volatile, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1)
+ {
+ return (boost::forward<A0>(a0).*f)(boost::forward<A1>(a1));
+ }
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1) const volatile, A0 a0, A1 a1)
+ {
+ return (a0.*f)(a1);
+ }
+ template <class Ret, class A, class A0, class A1, class A2>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2) const volatile,
+ BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2
+ )
+ {
+ return (boost::forward<A0>(a0).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
+ }
+ template <class Ret, class A, class A0, class A1, class A2>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2) const volatile,
+ A0 a0, A1 a1, A2 a2
+ )
+ {
+ return (a0.*f)(a1, a2);
+ }
+ template <class Ret, class A, class A0, class A1, class A2, class A3>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2, A3) const volatile,
+ BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3
+ )
+ {
+ return (boost::forward<A0>(a0).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
+ }
+ template <class Ret, class A, class A0, class A1, class A2, class A3>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2, A3) const volatile,
+ A0 a0, A1 a1, A2 a2, A3 a3
+ )
+ {
+ return (a0.*f)(a1, a2, a3);
+ }
+
+ // bullet 2
+ // ((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is not one of
+ // the types described in the previous item;
+ template <class Ret, class A, class A0>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(), BOOST_THREAD_RV_REF(A0) a0)
+ {
+ return ((*boost::forward<A0>(a0)).*f)();
+ }
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1), BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1)
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1));
+ }
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1), A0 a0, A1 a1)
+ {
+ return ((*a0).*f)(a1);
+ }
+ template <class Ret, class A, class A0, class A1, class A2>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, BOOST_THREAD_RV_REF(A2)),
+ BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
+ }
+ template <class Ret, class A, class A0, class A1, class A2>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2), A0 a0, A1 a1, A2 a2)
+ {
+ return ((*a0).*f)(a1, a2);
+ }
+ template <class Ret, class A, class A0, class A1, class A2, class A3>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, BOOST_THREAD_RV_REF(A2), BOOST_THREAD_RV_REF(A3)),
+ BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3)
+ );
+ }
+ template <class Ret, class A, class A0, class A1, class A2, class A3>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2, A3), A0 a0, A1 a1, A2 a2, A3 a3)
+ {
+ return ((*a0).*f)(a1, a2, a3);
+ }
+
+///
+ template <class Ret, class A, class A0>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)() const, BOOST_THREAD_RV_REF(A0) a0)
+ {
+ return ((*boost::forward<A0>(a0)).*f)();
+ }
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1) const,
+ BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1)
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1));
+ }
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1) const, BOOST_THREAD_RV_REF(A0) a0, A1 a1)
+ {
+ return ((*boost::forward<A0>(a0)).*f)(a1);
+ }
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1) const, A0 a0, A1 a1)
+ {
+ return ((*a0).*f)(a1);
+ }
+ template <class Ret, class A, class A0, class A1, class A2>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2) const,
+ BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
+ }
+ template <class Ret, class A, class A0, class A1, class A2>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2) const, A0 a0, A1 a1, A2 a2)
+ {
+ return ((*a0).*f)(a1, a2);
+ }
+ template <class Ret, class A, class A0, class A1, class A2, class A3>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2, A3) const,
+ BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
+ }
+ template <class Ret, class A, class A0, class A1, class A2, class A3>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2, A3) const,
+ A0 a0, A1 a1, A2 a2, A3 a3)
+ {
+ return ((*a0).*f)(a1, a2, a3);
+ }
+ ///
+ template <class Ret, class A, class A0>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)() volatile, BOOST_THREAD_RV_REF(A0) a0)
+ {
+ return ((*boost::forward<A0>(a0)).*f)();
+ }
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1) volatile,
+ BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1)
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1));
+ }
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1) volatile, A0 a0, A1 a1)
+ {
+ return ((*a0).*f)(a1);
+ }
+ template <class Ret, class A, class A0, class A1, class A2>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2) volatile,
+ BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
+ }
+ template <class Ret, class A, class A0, class A1, class A2>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2) volatile, A0 a0, A1 a1, A2 a2)
+ {
+ return ((*a0).*f)(a1, a2);
+ }
+ template <class Ret, class A, class A0, class A1, class A2, class A3>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2, A3) volatile,
+ BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
+ }
+ template <class Ret, class A, class A0, class A1, class A2, class A3>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2, A3) volatile, A0 a0, A1 a1, A2 a2, A3 a3)
+ {
+ return ((*a0).*f)(a1, a2, a3);
+ }
+ ///
+ template <class Ret, class A, class A0>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)() const volatile, BOOST_THREAD_RV_REF(A0) a0)
+ {
+ return ((*boost::forward<A0>(a0)).*f)();
+ }
+ template <class Ret, class A, class A0>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)() const volatile, A0 a0)
+ {
+ return ((*a0).*f)();
+ }
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1) const volatile,
+ BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1)
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1));
+ }
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1) const volatile, A0 a0, A1 a1)
+ {
+ return ((*a0).*f)(a1);
+ }
+ template <class Ret, class A, class A0, class A1, class A2>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2) const volatile,
+ BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
+ }
+ template <class Ret, class A, class A0, class A1, class A2>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2) const volatile,
+ A0 a0, A1 a1, A2 a2)
+ {
+ return ((*a0).*f)(a1, a2);
+ }
+ template <class Ret, class A, class A0, class A1, class A2, class A3>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2, A3) const volatile,
+ BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
+ }
+ template <class Ret, class A, class A0, class A1, class A2, class A3>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2, A3) const volatile,
+ A0 a0, A1 a1, A2 a2, A3 a3)
+ {
+ return ((*a0).*f)(a1, a2, a3);
+ }
+ // bullet 3
+ // t1.*f when N == 1 and f is a pointer to member data of a class T and t1 is an object of type T or a
+ // reference to an object of type T or a reference to an object of a type derived from T;
+// template <class Ret, class A, class A0>
+// inline
+// typename enable_if_c
+// <
+// is_base_of<A, typename remove_reference<A0>::type>::value,
+// typename detail::apply_cv<A0, A>::type&
+// >::type
+// invoke(Ret A::* f, BOOST_THREAD_RV_REF(A0) a0)
+// {
+// return boost::forward<A0>(a0).*f;
+// }
+
+ // bullet 4
+ // (*t1).*f when N == 1 and f is a pointer to member data of a class T and t1 is not one of the types
+ //described in the previous item;
+
+// template <class A0, class Ret, bool>
+// struct d4th_helper
+// {
+// };
+//
+// template <class A0, class Ret>
+// struct d4th_helper<A0, Ret, true>
+// {
+// typedef typename apply_cv<decltype(*declval<A0>()), Ret>::type type;
+// };
+//
+// template <class Ret, class A, class A0>
+// inline
+// typename detail::4th_helper<A, Ret,
+// !is_base_of<A,
+// typename remove_reference<A0>::type
+// >::value
+// >::type&
+// invoke(Ret A::* f, BOOST_THREAD_RV_REF(A0) a0)
+// {
+// return (*boost::forward<A0>(a0)).*f;
+// }
+
+// template <class Ret, class A, class A0>
+// inline
+// typename enable_if_c
+// <
+// !is_base_of<A, typename remove_reference<A0>::type>::value,
+// typename detail::ref_return1<Ret A::*, A0>::type
+// >::type
+// invoke(Ret A::* f, BOOST_THREAD_RV_REF(A0) a0)
+// {
+// return (*boost::forward<A0>(a0)).*f;
+// }
+
+ // bullet 5
+ // f(t1, t2, ..., tN) in all other cases.
+
+ template <class Ret, class Fp>
+ inline Ret do_invoke(mpl::false_, BOOST_THREAD_FWD_REF(Fp) f)
+ {
+ return boost::forward<Fp>(f)();
+ }
+ template <class Ret, class Fp>
+ inline Ret do_invoke(mpl::true_, BOOST_THREAD_FWD_REF(Fp) f)
+ {
+ return f();
+ }
+ template <class Ret, class Fp>
+ inline
+ typename disable_if_c
+ <
+ is_member_function_pointer<Fp>::value,
+ Ret
+ >::type
+ invoke(BOOST_THREAD_FWD_REF(Fp) f)
+ {
+ return boost::detail::do_invoke<Ret>(boost::is_pointer<Fp>(), boost::forward<Fp>(f));
+ }
+
+ template <class Ret, class Fp, class A1>
+ inline Ret do_invoke(mpl::false_, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1)
+ {
+ return boost::forward<Fp>(f)(boost::forward<A1>(a1));
+ }
+ template <class Ret, class Fp, class A1>
+ inline Ret do_invoke(mpl::true_, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1)
+ {
+ return f(boost::forward<A1>(a1));
+ }
+ template <class Ret, class Fp, class A1>
+ inline
+ typename disable_if_c
+ <
+ is_member_function_pointer<Fp>::value,
+ Ret
+ >::type
+ invoke(BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1)
+ {
+ return boost::detail::do_invoke<Ret>(boost::is_pointer<Fp>(), boost::forward<Fp>(f), boost::forward<A1>(a1));
+ }
+
+ template <class Ret, class Fp, class A1, class A2>
+ inline Ret do_invoke(mpl::false_, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
+ {
+ return boost::forward<Fp>(f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
+ }
+ template <class Ret, class Fp, class A1, class A2>
+ inline Ret do_invoke(mpl::true_, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
+ {
+ return f(boost::forward<A1>(a1), boost::forward<A2>(a2));
+ }
+ template <class Ret, class Fp, class A1, class A2>
+ inline
+ typename disable_if_c
+ <
+ is_member_function_pointer<Fp>::value,
+ Ret
+ >::type
+ invoke(BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
+ {
+ return boost::detail::do_invoke<Ret>(boost::is_pointer<Fp>(), boost::forward<Fp>(f), boost::forward<A1>(a1), boost::forward<A2>(a2));
+ }
+
+ template <class Ret, class Fp, class A1, class A2, class A3>
+ inline Ret do_invoke(mpl::false_, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
+ {
+ return boost::forward<Fp>(f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
+ }
+ template <class Ret, class Fp, class A1, class A2, class A3>
+ inline Ret do_invoke(mpl::true_, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
+ {
+ return f(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
+ }
+ template <class Ret, class Fp, class A1, class A2, class A3>
+ inline
+ typename disable_if_c
+ <
+ is_member_function_pointer<Fp>::value,
+ Ret
+ >::type
+ invoke(BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
+ {
+ return boost::detail::do_invoke<Ret>(boost::is_pointer<Fp>(), boost::forward<Fp>(f), boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
+ }
+
+
+ template <class Ret, class Fp, class A1>
+ inline Ret do_invoke(mpl::false_, BOOST_THREAD_FWD_REF(Fp) f, A1 a1)
+ {
+ return boost::forward<Fp>(f)(a1);
+ }
+ template <class Ret, class Fp, class A1>
+ inline Ret do_invoke(mpl::true_, BOOST_THREAD_FWD_REF(Fp) f, A1 a1)
+ {
+ return f(a1);
+ }
+ template <class Ret, class Fp, class A1>
+ inline
+ typename disable_if_c
+ <
+ is_member_function_pointer<Fp>::value,
+ Ret
+ >::type
+ invoke(BOOST_THREAD_FWD_REF(Fp) f, A1 a1)
+ {
+ return boost::detail::do_invoke<Ret>(boost::is_pointer<Fp>(), boost::forward<Fp>(f), a1);
+ }
+
+ template <class Ret, class Fp, class A1, class A2>
+ inline Ret do_invoke(mpl::false_, BOOST_THREAD_FWD_REF(Fp) f, A1 a1, A2 a2)
+ {
+ return boost::forward<Fp>(f)(a1, a2);
+ }
+ template <class Ret, class Fp, class A1, class A2>
+ inline Ret do_invoke(mpl::true_, BOOST_THREAD_FWD_REF(Fp) f, A1 a1, A2 a2)
+ {
+ return f(a1, a2);
+ }
+ template <class Ret, class Fp, class A1, class A2>
+ inline
+ typename disable_if_c
+ <
+ is_member_function_pointer<Fp>::value,
+ Ret
+ >::type
+ invoke(BOOST_THREAD_FWD_REF(Fp) f, A1 a1, A2 a2)
+ {
+ return boost::detail::do_invoke<Ret>(boost::is_pointer<Fp>(), boost::forward<Fp>(f), a1, a2);
+ }
+
+ template <class Ret, class Fp, class A1, class A2, class A3>
+ inline Ret do_invoke(mpl::false_, BOOST_THREAD_FWD_REF(Fp) f, A1 a1, A2 a2, A3 a3)
+ {
+ return boost::forward<Fp>(f)(a1, a2, a3);
+ }
+ template <class Ret, class Fp, class A1, class A2, class A3>
+ inline Ret do_invoke(mpl::true_, BOOST_THREAD_FWD_REF(Fp) f, A1 a1, A2 a2, A3 a3)
+ {
+ return f(a1, a2, a3);
+ }
+ template <class Ret, class Fp, class A1, class A2, class A3>
+ inline
+ typename disable_if_c
+ <
+ is_member_function_pointer<Fp>::value,
+ Ret
+ >::type
+ invoke(BOOST_THREAD_FWD_REF(Fp) f, A1 a1, A2 a2, A3 a3)
+ {
+ return boost::detail::do_invoke<Ret>(boost::is_pointer<Fp>(), boost::forward<Fp>(f), a1, a2, a3);
+ }
+
+
+ ///
+ template <class Ret, class Fp>
+ inline
+ typename disable_if_c
+ <
+ is_member_function_pointer<Fp>::value,
+ Ret
+ >::type
+ invoke(Fp &f)
+ {
+ return f();
+ }
+ template <class Ret, class Fp, class A1>
+ inline
+ typename disable_if_c
+ <
+ is_member_function_pointer<Fp>::value,
+ Ret
+ >::type
+ invoke(Fp &f, BOOST_THREAD_RV_REF(A1) a1)
+ {
+ return f(boost::forward<A1>(a1));
+ }
+ template <class Ret, class Fp, class A1>
+ inline
+ typename disable_if_c
+ <
+ is_member_function_pointer<Fp>::value,
+ Ret
+ >::type
+ invoke(Fp &f, A1 a1)
+ {
+ return f(a1);
+ }
+ template <class Ret, class Fp, class A1, class A2>
+ inline
+ typename disable_if_c
+ <
+ is_member_function_pointer<Fp>::value,
+ Ret
+ >::type
+ invoke(Fp &f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
+ {
+ return f(boost::forward<A1>(a1), boost::forward<A2>(a2));
+ }
+ template <class Ret, class Fp, class A1, class A2>
+ inline
+ typename disable_if_c
+ <
+ is_member_function_pointer<Fp>::value,
+ Ret
+ >::type
+ invoke(Fp &f, A1 a1, A2 a2)
+ {
+ return f(a1, a2);
+ }
+ template <class Ret, class Fp, class A1, class A2, class A3>
+ inline
+ typename disable_if_c
+ <
+ is_member_function_pointer<Fp>::value,
+ Ret
+ >::type
+ invoke(Fp &f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
+ {
+ return f(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
+ }
+ template <class Ret, class Fp, class A1, class A2, class A3>
+ inline
+ typename disable_if_c
+ <
+ is_member_function_pointer<Fp>::value,
+ Ret
+ >::type
+ invoke(Fp &f, A1 a1, A2 a2, A3 a3)
+ {
+ return f(a1, a2, a3);
+ }
+ ///
+
+#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
+
+#endif // all
+ }
+ }
+
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/detail/invoker.hpp b/src/third_party/boost-1.60.0/boost/thread/detail/invoker.hpp
new file mode 100644
index 00000000000..9f38e9798dd
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/detail/invoker.hpp
@@ -0,0 +1,762 @@
+// 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)
+
+// 2013/04 Vicente J. Botet Escriba
+// Provide implementation up to 9 parameters when BOOST_NO_CXX11_VARIADIC_TEMPLATES is defined.
+// Make use of Boost.Move
+// Make use of Boost.Tuple (movable)
+// 2012/11 Vicente J. Botet Escriba
+// Adapt to boost libc++ implementation
+
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+// The invoker code is based on the one from libcxx.
+//===----------------------------------------------------------------------===//
+
+#ifndef BOOST_THREAD_DETAIL_INVOKER_HPP
+#define BOOST_THREAD_DETAIL_INVOKER_HPP
+
+#include <boost/config.hpp>
+
+#include <boost/utility/result_of.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/detail/invoke.hpp>
+#include <boost/thread/detail/make_tuple_indices.hpp>
+#include <boost/thread/csbl/tuple.hpp>
+#include <boost/tuple/tuple.hpp>
+
+#include <boost/thread/detail/variadic_header.hpp>
+
+namespace boost
+{
+ namespace detail
+ {
+
+#if defined(BOOST_THREAD_PROVIDES_INVOKE) && ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && ! defined(BOOST_NO_CXX11_HDR_TUPLE)
+
+ template <class Fp, class ... Args>
+ class invoker
+ {
+ //typedef typename decay<Fp>::type Fpd;
+ //typedef tuple<typename decay<Args>::type...> Argsd;
+
+ //csbl::tuple<Fpd, Argsd...> f_;
+ csbl::tuple<Fp, Args...> f_;
+
+ public:
+ BOOST_THREAD_COPYABLE_AND_MOVABLE( invoker)
+ //typedef typename invoke_of<_Fp, _Args...>::type Rp;
+ typedef typename result_of<Fp(Args...)>::type result_type;
+
+ template <class F, class ... As>
+ BOOST_SYMBOL_VISIBLE
+ explicit invoker(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(As)... args)
+ : f_(boost::forward<F>(f), boost::forward<As>(args)...)
+ {}
+
+ BOOST_SYMBOL_VISIBLE
+ invoker(BOOST_THREAD_RV_REF(invoker) f) : f_(boost::move(BOOST_THREAD_RV(f).f_))
+ {}
+
+ BOOST_SYMBOL_VISIBLE
+ invoker( const invoker& f) : f_(f.f_)
+ {}
+
+ BOOST_SYMBOL_VISIBLE
+ invoker& operator=(BOOST_THREAD_RV_REF(invoker) f)
+ {
+ if (this != &f)
+ {
+ f_ = boost::move(BOOST_THREAD_RV(f).f_);
+ }
+ return *this;
+ }
+
+ BOOST_SYMBOL_VISIBLE
+ invoker& operator=( BOOST_THREAD_COPY_ASSIGN_REF(invoker) f)
+ {
+ if (this != &f)
+ {
+ f_ = f.f_;
+ }
+ return *this;
+ }
+
+ result_type operator()()
+ {
+ typedef typename make_tuple_indices<1+sizeof...(Args), 1>::type Index;
+ return execute(Index());
+ }
+ private:
+ template <size_t ...Indices>
+ result_type
+ execute(tuple_indices<Indices...>)
+ {
+ return detail::invoke(boost::move(csbl::get<0>(f_)), boost::move(csbl::get<Indices>(f_))...);
+ }
+ };
+
+ template <class R, class Fp, class ... Args>
+ class invoker_ret
+ {
+ //typedef typename decay<Fp>::type Fpd;
+ //typedef tuple<typename decay<Args>::type...> Argsd;
+
+ //csbl::tuple<Fpd, Argsd...> f_;
+ csbl::tuple<Fp, Args...> f_;
+
+ public:
+ BOOST_THREAD_COPYABLE_AND_MOVABLE( invoker_ret)
+ typedef R result_type;
+
+ template <class F, class ... As>
+ BOOST_SYMBOL_VISIBLE
+ explicit invoker_ret(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(As)... args)
+ : f_(boost::forward<F>(f), boost::forward<As>(args)...)
+ {}
+
+ BOOST_SYMBOL_VISIBLE
+ invoker_ret(BOOST_THREAD_RV_REF(invoker_ret) f) : f_(boost::move(BOOST_THREAD_RV(f).f_))
+ {}
+
+ result_type operator()()
+ {
+ typedef typename make_tuple_indices<1+sizeof...(Args), 1>::type Index;
+ return execute(Index());
+ }
+ private:
+ template <size_t ...Indices>
+ result_type
+ execute(tuple_indices<Indices...>)
+ {
+ return detail::invoke<R>(boost::move(csbl::get<0>(f_)), boost::move(csbl::get<Indices>(f_))...);
+ }
+ };
+ //BOOST_THREAD_DCL_MOVABLE_BEG(X) invoker<Fp> BOOST_THREAD_DCL_MOVABLE_END
+#else
+
+#if ! defined BOOST_MSVC && defined(BOOST_THREAD_PROVIDES_INVOKE)
+
+#define BOOST_THREAD_RV_REF_ARG_T(z, n, unused) BOOST_PP_COMMA_IF(n) BOOST_THREAD_RV_REF(Arg##n)
+#define BOOST_THREAD_RV_REF_A_T(z, n, unused) BOOST_PP_COMMA_IF(n) BOOST_THREAD_RV_REF(A##n)
+#define BOOST_THREAD_RV_REF_ARG(z, n, unused) , BOOST_THREAD_RV_REF(Arg##n) arg##n
+#define BOOST_THREAD_FWD_REF_A(z, n, unused) , BOOST_THREAD_FWD_REF(A##n) arg##n
+#define BOOST_THREAD_FWD_REF_ARG(z, n, unused) , BOOST_THREAD_FWD_REF(Arg##n) arg##n
+#define BOOST_THREAD_FWD_PARAM(z, n, unused) , boost::forward<Arg##n>(arg##n)
+#define BOOST_THREAD_FWD_PARAM_A(z, n, unused) , boost::forward<A##n>(arg##n)
+#define BOOST_THREAD_DCL(z, n, unused) Arg##n v##n;
+#define BOOST_THREAD_MOVE_PARAM(z, n, unused) , v##n(boost::move(arg##n))
+#define BOOST_THREAD_FORWARD_PARAM_A(z, n, unused) , v##n(boost::forward<A##n>(arg##n))
+#define BOOST_THREAD_MOVE_RHS_PARAM(z, n, unused) , v##n(boost::move(x.v##n))
+#define BOOST_THREAD_MOVE_DCL(z, n, unused) , boost::move(v##n)
+#define BOOST_THREAD_MOVE_DCL_T(z, n, unused) BOOST_PP_COMMA_IF(n) boost::move(v##n)
+#define BOOST_THREAD_ARG_DEF(z, n, unused) , class Arg##n = tuples::null_type
+
+ template <class Fp, class Arg = tuples::null_type
+ BOOST_PP_REPEAT(BOOST_THREAD_MAX_ARGS, BOOST_THREAD_ARG_DEF, ~)
+ >
+ class invoker;
+
+#define BOOST_THREAD_ASYNC_FUNCT(z, n, unused) \
+ template <class Fp BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, class Arg) > \
+ class invoker<Fp BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, Arg)> \
+ { \
+ Fp fp_; \
+ BOOST_PP_REPEAT(n, BOOST_THREAD_DCL, ~) \
+ public: \
+ BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker) \
+ typedef typename result_of<Fp(BOOST_PP_ENUM_PARAMS(n, Arg))>::type result_type; \
+ \
+ template <class F BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, class A) > \
+ BOOST_SYMBOL_VISIBLE \
+ explicit invoker(BOOST_THREAD_FWD_REF(F) f \
+ BOOST_PP_REPEAT(n, BOOST_THREAD_FWD_REF_A, ~) \
+ ) \
+ : fp_(boost::forward<F>(f)) \
+ BOOST_PP_REPEAT(n, BOOST_THREAD_FORWARD_PARAM_A, ~) \
+ {} \
+ \
+ BOOST_SYMBOL_VISIBLE \
+ invoker(BOOST_THREAD_RV_REF(invoker) x) \
+ : fp_(boost::move(x.fp_)) \
+ BOOST_PP_REPEAT(n, BOOST_THREAD_MOVE_RHS_PARAM, ~) \
+ {} \
+ \
+ result_type operator()() { \
+ return detail::invoke(boost::move(fp_) \
+ BOOST_PP_REPEAT(n, BOOST_THREAD_MOVE_DCL, ~) \
+ ); \
+ } \
+ }; \
+ \
+ template <class R BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, class Arg) > \
+ class invoker<R(*)(BOOST_PP_REPEAT(n, BOOST_THREAD_RV_REF_ARG_T, ~)) BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, Arg)> \
+ { \
+ typedef R(*Fp)(BOOST_PP_REPEAT(n, BOOST_THREAD_RV_REF_ARG_T, ~)); \
+ Fp fp_; \
+ BOOST_PP_REPEAT(n, BOOST_THREAD_DCL, ~) \
+ public: \
+ BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker) \
+ typedef typename result_of<Fp(BOOST_PP_ENUM_PARAMS(n, Arg))>::type result_type; \
+ \
+ template <class R2 BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, class A) > \
+ BOOST_SYMBOL_VISIBLE \
+ explicit invoker(R2(*f)(BOOST_PP_REPEAT(n, BOOST_THREAD_RV_REF_A_T, ~)) \
+ BOOST_PP_REPEAT(n, BOOST_THREAD_FWD_REF_A, ~) \
+ ) \
+ : fp_(f) \
+ BOOST_PP_REPEAT(n, BOOST_THREAD_FORWARD_PARAM_A, ~) \
+ {} \
+ \
+ BOOST_SYMBOL_VISIBLE \
+ invoker(BOOST_THREAD_RV_REF(invoker) x) \
+ : fp_(x.fp_) \
+ BOOST_PP_REPEAT(n, BOOST_THREAD_MOVE_RHS_PARAM, ~) \
+ {} \
+ \
+ result_type operator()() { \
+ return fp_( \
+ BOOST_PP_REPEAT(n, BOOST_THREAD_MOVE_DCL_T, ~) \
+ ); \
+ } \
+ };
+
+ BOOST_PP_REPEAT(BOOST_THREAD_MAX_ARGS, BOOST_THREAD_ASYNC_FUNCT, ~)
+
+ #undef BOOST_THREAD_RV_REF_ARG_T
+ #undef BOOST_THREAD_RV_REF_ARG
+ #undef BOOST_THREAD_FWD_REF_ARG
+ #undef BOOST_THREAD_FWD_REF_A
+ #undef BOOST_THREAD_FWD_PARAM
+ #undef BOOST_THREAD_FWD_PARAM_A
+ #undef BOOST_THREAD_DCL
+ #undef BOOST_THREAD_MOVE_PARAM
+ #undef BOOST_THREAD_MOVE_RHS_PARAM
+ #undef BOOST_THREAD_MOVE_DCL
+ #undef BOOST_THREAD_ARG_DEF
+ #undef BOOST_THREAD_ASYNC_FUNCT
+
+#else
+
+ template <class Fp,
+ class T0 = tuples::null_type, class T1 = tuples::null_type, class T2 = tuples::null_type,
+ class T3 = tuples::null_type, class T4 = tuples::null_type, class T5 = tuples::null_type,
+ class T6 = tuples::null_type, class T7 = tuples::null_type, class T8 = tuples::null_type
+ , class T9 = tuples::null_type
+ >
+ class invoker;
+
+ template <class Fp,
+ class T0 , class T1 , class T2 ,
+ class T3 , class T4 , class T5 ,
+ class T6 , class T7 , class T8 >
+ class invoker<Fp, T0, T1, T2, T3, T4, T5, T6, T7, T8>
+ {
+ Fp fp_;
+ T0 v0_;
+ T1 v1_;
+ T2 v2_;
+ T3 v3_;
+ T4 v4_;
+ T5 v5_;
+ T6 v6_;
+ T7 v7_;
+ T8 v8_;
+ //::boost::tuple<Fp, T0, T1, T2, T3, T4, T5, T6, T7, T8> f_;
+
+ public:
+ BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker)
+ typedef typename result_of<Fp(T0, T1, T2, T3, T4, T5, T6, T7, T8)>::type result_type;
+
+ BOOST_SYMBOL_VISIBLE
+ explicit invoker(BOOST_THREAD_FWD_REF(Fp) f
+ , BOOST_THREAD_RV_REF(T0) a0
+ , BOOST_THREAD_RV_REF(T1) a1
+ , BOOST_THREAD_RV_REF(T2) a2
+ , BOOST_THREAD_RV_REF(T3) a3
+ , BOOST_THREAD_RV_REF(T4) a4
+ , BOOST_THREAD_RV_REF(T5) a5
+ , BOOST_THREAD_RV_REF(T6) a6
+ , BOOST_THREAD_RV_REF(T7) a7
+ , BOOST_THREAD_RV_REF(T8) a8
+ )
+ : fp_(boost::move(f))
+ , v0_(boost::move(a0))
+ , v1_(boost::move(a1))
+ , v2_(boost::move(a2))
+ , v3_(boost::move(a3))
+ , v4_(boost::move(a4))
+ , v5_(boost::move(a5))
+ , v6_(boost::move(a6))
+ , v7_(boost::move(a7))
+ , v8_(boost::move(a8))
+ {}
+
+ BOOST_SYMBOL_VISIBLE
+ invoker(BOOST_THREAD_RV_REF(invoker) f)
+ : fp_(boost::move(BOOST_THREAD_RV(f).fp))
+ , v0_(boost::move(BOOST_THREAD_RV(f).v0_))
+ , v1_(boost::move(BOOST_THREAD_RV(f).v1_))
+ , v2_(boost::move(BOOST_THREAD_RV(f).v2_))
+ , v3_(boost::move(BOOST_THREAD_RV(f).v3_))
+ , v4_(boost::move(BOOST_THREAD_RV(f).v4_))
+ , v5_(boost::move(BOOST_THREAD_RV(f).v5_))
+ , v6_(boost::move(BOOST_THREAD_RV(f).v6_))
+ , v7_(boost::move(BOOST_THREAD_RV(f).v7_))
+ , v8_(boost::move(BOOST_THREAD_RV(f).v8_))
+ {}
+
+ result_type operator()()
+ {
+ return detail::invoke(boost::move(fp_)
+ , boost::move(v0_)
+ , boost::move(v1_)
+ , boost::move(v2_)
+ , boost::move(v3_)
+ , boost::move(v4_)
+ , boost::move(v5_)
+ , boost::move(v6_)
+ , boost::move(v7_)
+ , boost::move(v8_)
+ );
+ }
+ };
+ template <class Fp, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7 >
+ class invoker<Fp, T0, T1, T2, T3, T4, T5, T6, T7>
+ {
+ Fp fp_;
+ T0 v0_;
+ T1 v1_;
+ T2 v2_;
+ T3 v3_;
+ T4 v4_;
+ T5 v5_;
+ T6 v6_;
+ T7 v7_;
+ public:
+ BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker)
+ typedef typename result_of<Fp(T0, T1, T2, T3, T4, T5, T6, T7)>::type result_type;
+
+ BOOST_SYMBOL_VISIBLE
+ explicit invoker(BOOST_THREAD_FWD_REF(Fp) f
+ , BOOST_THREAD_RV_REF(T0) a0
+ , BOOST_THREAD_RV_REF(T1) a1
+ , BOOST_THREAD_RV_REF(T2) a2
+ , BOOST_THREAD_RV_REF(T3) a3
+ , BOOST_THREAD_RV_REF(T4) a4
+ , BOOST_THREAD_RV_REF(T5) a5
+ , BOOST_THREAD_RV_REF(T6) a6
+ , BOOST_THREAD_RV_REF(T7) a7
+ )
+ : fp_(boost::move(f))
+ , v0_(boost::move(a0))
+ , v1_(boost::move(a1))
+ , v2_(boost::move(a2))
+ , v3_(boost::move(a3))
+ , v4_(boost::move(a4))
+ , v5_(boost::move(a5))
+ , v6_(boost::move(a6))
+ , v7_(boost::move(a7))
+ {}
+
+ BOOST_SYMBOL_VISIBLE
+ invoker(BOOST_THREAD_RV_REF(invoker) f)
+ : fp_(boost::move(BOOST_THREAD_RV(f).fp))
+ , v0_(boost::move(BOOST_THREAD_RV(f).v0_))
+ , v1_(boost::move(BOOST_THREAD_RV(f).v1_))
+ , v2_(boost::move(BOOST_THREAD_RV(f).v2_))
+ , v3_(boost::move(BOOST_THREAD_RV(f).v3_))
+ , v4_(boost::move(BOOST_THREAD_RV(f).v4_))
+ , v5_(boost::move(BOOST_THREAD_RV(f).v5_))
+ , v6_(boost::move(BOOST_THREAD_RV(f).v6_))
+ , v7_(boost::move(BOOST_THREAD_RV(f).v7_))
+ {}
+
+ result_type operator()()
+ {
+ return detail::invoke(boost::move(fp_)
+ , boost::move(v0_)
+ , boost::move(v1_)
+ , boost::move(v2_)
+ , boost::move(v3_)
+ , boost::move(v4_)
+ , boost::move(v5_)
+ , boost::move(v6_)
+ , boost::move(v7_)
+ );
+ }
+ };
+ template <class Fp, class T0, class T1, class T2, class T3, class T4, class T5, class T6>
+ class invoker<Fp, T0, T1, T2, T3, T4, T5, T6>
+ {
+ Fp fp_;
+ T0 v0_;
+ T1 v1_;
+ T2 v2_;
+ T3 v3_;
+ T4 v4_;
+ T5 v5_;
+ T6 v6_;
+ public:
+ BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker)
+ typedef typename result_of<Fp(T0, T1, T2, T3, T4, T5, T6)>::type result_type;
+
+ BOOST_SYMBOL_VISIBLE
+ explicit invoker(BOOST_THREAD_FWD_REF(Fp) f
+ , BOOST_THREAD_RV_REF(T0) a0
+ , BOOST_THREAD_RV_REF(T1) a1
+ , BOOST_THREAD_RV_REF(T2) a2
+ , BOOST_THREAD_RV_REF(T3) a3
+ , BOOST_THREAD_RV_REF(T4) a4
+ , BOOST_THREAD_RV_REF(T5) a5
+ , BOOST_THREAD_RV_REF(T6) a6
+ )
+ : fp_(boost::move(f))
+ , v0_(boost::move(a0))
+ , v1_(boost::move(a1))
+ , v2_(boost::move(a2))
+ , v3_(boost::move(a3))
+ , v4_(boost::move(a4))
+ , v5_(boost::move(a5))
+ , v6_(boost::move(a6))
+ {}
+
+ BOOST_SYMBOL_VISIBLE
+ invoker(BOOST_THREAD_RV_REF(invoker) f)
+ : fp_(boost::move(BOOST_THREAD_RV(f).fp))
+ , v0_(boost::move(BOOST_THREAD_RV(f).v0_))
+ , v1_(boost::move(BOOST_THREAD_RV(f).v1_))
+ , v2_(boost::move(BOOST_THREAD_RV(f).v2_))
+ , v3_(boost::move(BOOST_THREAD_RV(f).v3_))
+ , v4_(boost::move(BOOST_THREAD_RV(f).v4_))
+ , v5_(boost::move(BOOST_THREAD_RV(f).v5_))
+ , v6_(boost::move(BOOST_THREAD_RV(f).v6_))
+ {}
+
+ result_type operator()()
+ {
+ return detail::invoke(boost::move(fp_)
+ , boost::move(v0_)
+ , boost::move(v1_)
+ , boost::move(v2_)
+ , boost::move(v3_)
+ , boost::move(v4_)
+ , boost::move(v5_)
+ , boost::move(v6_)
+ );
+ }
+ };
+ template <class Fp, class T0, class T1, class T2, class T3, class T4, class T5>
+ class invoker<Fp, T0, T1, T2, T3, T4, T5>
+ {
+ Fp fp_;
+ T0 v0_;
+ T1 v1_;
+ T2 v2_;
+ T3 v3_;
+ T4 v4_;
+ T5 v5_;
+ public:
+ BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker)
+ typedef typename result_of<Fp(T0, T1, T2, T3, T4, T5)>::type result_type;
+
+ BOOST_SYMBOL_VISIBLE
+ explicit invoker(BOOST_THREAD_FWD_REF(Fp) f
+ , BOOST_THREAD_RV_REF(T0) a0
+ , BOOST_THREAD_RV_REF(T1) a1
+ , BOOST_THREAD_RV_REF(T2) a2
+ , BOOST_THREAD_RV_REF(T3) a3
+ , BOOST_THREAD_RV_REF(T4) a4
+ , BOOST_THREAD_RV_REF(T5) a5
+ )
+ : fp_(boost::move(f))
+ , v0_(boost::move(a0))
+ , v1_(boost::move(a1))
+ , v2_(boost::move(a2))
+ , v3_(boost::move(a3))
+ , v4_(boost::move(a4))
+ , v5_(boost::move(a5))
+ {}
+
+ BOOST_SYMBOL_VISIBLE
+ invoker(BOOST_THREAD_RV_REF(invoker) f)
+ : fp_(boost::move(BOOST_THREAD_RV(f).fp))
+ , v0_(boost::move(BOOST_THREAD_RV(f).v0_))
+ , v1_(boost::move(BOOST_THREAD_RV(f).v1_))
+ , v2_(boost::move(BOOST_THREAD_RV(f).v2_))
+ , v3_(boost::move(BOOST_THREAD_RV(f).v3_))
+ , v4_(boost::move(BOOST_THREAD_RV(f).v4_))
+ , v5_(boost::move(BOOST_THREAD_RV(f).v5_))
+ {}
+
+ result_type operator()()
+ {
+ return detail::invoke(boost::move(fp_)
+ , boost::move(v0_)
+ , boost::move(v1_)
+ , boost::move(v2_)
+ , boost::move(v3_)
+ , boost::move(v4_)
+ , boost::move(v5_)
+ );
+ }
+ };
+ template <class Fp, class T0, class T1, class T2, class T3, class T4>
+ class invoker<Fp, T0, T1, T2, T3, T4>
+ {
+ Fp fp_;
+ T0 v0_;
+ T1 v1_;
+ T2 v2_;
+ T3 v3_;
+ T4 v4_;
+ public:
+ BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker)
+ typedef typename result_of<Fp(T0, T1, T2, T3, T4)>::type result_type;
+
+ BOOST_SYMBOL_VISIBLE
+ explicit invoker(BOOST_THREAD_FWD_REF(Fp) f
+ , BOOST_THREAD_RV_REF(T0) a0
+ , BOOST_THREAD_RV_REF(T1) a1
+ , BOOST_THREAD_RV_REF(T2) a2
+ , BOOST_THREAD_RV_REF(T3) a3
+ , BOOST_THREAD_RV_REF(T4) a4
+ )
+ : fp_(boost::move(f))
+ , v0_(boost::move(a0))
+ , v1_(boost::move(a1))
+ , v2_(boost::move(a2))
+ , v3_(boost::move(a3))
+ , v4_(boost::move(a4))
+ {}
+
+ BOOST_SYMBOL_VISIBLE
+ invoker(BOOST_THREAD_RV_REF(invoker) f)
+ : fp_(boost::move(BOOST_THREAD_RV(f).fp))
+ , v0_(boost::move(BOOST_THREAD_RV(f).v0_))
+ , v1_(boost::move(BOOST_THREAD_RV(f).v1_))
+ , v2_(boost::move(BOOST_THREAD_RV(f).v2_))
+ , v3_(boost::move(BOOST_THREAD_RV(f).v3_))
+ , v4_(boost::move(BOOST_THREAD_RV(f).v4_))
+ {}
+
+ result_type operator()()
+ {
+ return detail::invoke(boost::move(fp_)
+ , boost::move(v0_)
+ , boost::move(v1_)
+ , boost::move(v2_)
+ , boost::move(v3_)
+ , boost::move(v4_)
+ );
+ }
+ };
+ template <class Fp, class T0, class T1, class T2, class T3>
+ class invoker<Fp, T0, T1, T2, T3>
+ {
+ Fp fp_;
+ T0 v0_;
+ T1 v1_;
+ T2 v2_;
+ T3 v3_;
+ public:
+ BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker)
+ typedef typename result_of<Fp(T0, T1, T2, T3)>::type result_type;
+
+ BOOST_SYMBOL_VISIBLE
+ explicit invoker(BOOST_THREAD_FWD_REF(Fp) f
+ , BOOST_THREAD_RV_REF(T0) a0
+ , BOOST_THREAD_RV_REF(T1) a1
+ , BOOST_THREAD_RV_REF(T2) a2
+ , BOOST_THREAD_RV_REF(T3) a3
+ )
+ : fp_(boost::move(f))
+ , v0_(boost::move(a0))
+ , v1_(boost::move(a1))
+ , v2_(boost::move(a2))
+ , v3_(boost::move(a3))
+ {}
+
+ BOOST_SYMBOL_VISIBLE
+ invoker(BOOST_THREAD_RV_REF(invoker) f)
+ : fp_(boost::move(BOOST_THREAD_RV(f).fp))
+ , v0_(boost::move(BOOST_THREAD_RV(f).v0_))
+ , v1_(boost::move(BOOST_THREAD_RV(f).v1_))
+ , v2_(boost::move(BOOST_THREAD_RV(f).v2_))
+ , v3_(boost::move(BOOST_THREAD_RV(f).v3_))
+ {}
+
+ result_type operator()()
+ {
+ return detail::invoke(boost::move(fp_)
+ , boost::move(v0_)
+ , boost::move(v1_)
+ , boost::move(v2_)
+ , boost::move(v3_)
+ );
+ }
+ };
+ template <class Fp, class T0, class T1, class T2>
+ class invoker<Fp, T0, T1, T2>
+ {
+ Fp fp_;
+ T0 v0_;
+ T1 v1_;
+ T2 v2_;
+ public:
+ BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker)
+ typedef typename result_of<Fp(T0, T1, T2)>::type result_type;
+
+ BOOST_SYMBOL_VISIBLE
+ explicit invoker(BOOST_THREAD_FWD_REF(Fp) f
+ , BOOST_THREAD_RV_REF(T0) a0
+ , BOOST_THREAD_RV_REF(T1) a1
+ , BOOST_THREAD_RV_REF(T2) a2
+ )
+ : fp_(boost::move(f))
+ , v0_(boost::move(a0))
+ , v1_(boost::move(a1))
+ , v2_(boost::move(a2))
+ {}
+
+ BOOST_SYMBOL_VISIBLE
+ invoker(BOOST_THREAD_RV_REF(invoker) f)
+ : fp_(boost::move(BOOST_THREAD_RV(f).fp))
+ , v0_(boost::move(BOOST_THREAD_RV(f).v0_))
+ , v1_(boost::move(BOOST_THREAD_RV(f).v1_))
+ , v2_(boost::move(BOOST_THREAD_RV(f).v2_))
+ {}
+
+ result_type operator()()
+ {
+ return detail::invoke(boost::move(fp_)
+ , boost::move(v0_)
+ , boost::move(v1_)
+ , boost::move(v2_)
+ );
+ }
+ };
+ template <class Fp, class T0, class T1>
+ class invoker<Fp, T0, T1>
+ {
+ Fp fp_;
+ T0 v0_;
+ T1 v1_;
+ public:
+ BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker)
+ typedef typename result_of<Fp(T0, T1)>::type result_type;
+
+ BOOST_SYMBOL_VISIBLE
+ explicit invoker(BOOST_THREAD_FWD_REF(Fp) f
+ , BOOST_THREAD_RV_REF(T0) a0
+ , BOOST_THREAD_RV_REF(T1) a1
+ )
+ : fp_(boost::move(f))
+ , v0_(boost::move(a0))
+ , v1_(boost::move(a1))
+ {}
+
+ BOOST_SYMBOL_VISIBLE
+ invoker(BOOST_THREAD_RV_REF(invoker) f)
+ : fp_(boost::move(BOOST_THREAD_RV(f).fp))
+ , v0_(boost::move(BOOST_THREAD_RV(f).v0_))
+ , v1_(boost::move(BOOST_THREAD_RV(f).v1_))
+ {}
+
+ result_type operator()()
+ {
+ return detail::invoke(boost::move(fp_)
+ , boost::move(v0_)
+ , boost::move(v1_)
+ );
+ }
+ };
+ template <class Fp, class T0>
+ class invoker<Fp, T0>
+ {
+ Fp fp_;
+ T0 v0_;
+ public:
+ BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker)
+ typedef typename result_of<Fp(T0)>::type result_type;
+
+ BOOST_SYMBOL_VISIBLE
+ explicit invoker(BOOST_THREAD_FWD_REF(Fp) f
+ , BOOST_THREAD_RV_REF(T0) a0
+ )
+ : fp_(boost::move(f))
+ , v0_(boost::move(a0))
+ {}
+
+ BOOST_SYMBOL_VISIBLE
+ invoker(BOOST_THREAD_RV_REF(invoker) f)
+ : fp_(boost::move(BOOST_THREAD_RV(f).fp))
+ , v0_(boost::move(BOOST_THREAD_RV(f).v0_))
+ {}
+
+ result_type operator()()
+ {
+ return detail::invoke(boost::move(fp_)
+ , boost::move(v0_)
+ );
+ }
+ };
+ template <class Fp>
+ class invoker<Fp>
+ {
+ Fp fp_;
+ public:
+ BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker)
+ typedef typename result_of<Fp()>::type result_type;
+ BOOST_SYMBOL_VISIBLE
+ explicit invoker(BOOST_THREAD_FWD_REF(Fp) f)
+ : fp_(boost::move(f))
+ {}
+
+ BOOST_SYMBOL_VISIBLE
+ invoker(BOOST_THREAD_RV_REF(invoker) f)
+ : fp_(boost::move(f.fp_))
+ {}
+ result_type operator()()
+ {
+ return fp_();
+ }
+ };
+ template <class R>
+ class invoker<R(*)()>
+ {
+ typedef R(*Fp)();
+ Fp fp_;
+ public:
+ BOOST_THREAD_COPYABLE_AND_MOVABLE(invoker)
+ typedef typename result_of<Fp()>::type result_type;
+ BOOST_SYMBOL_VISIBLE
+ explicit invoker(Fp f)
+ : fp_(f)
+ {}
+
+ BOOST_SYMBOL_VISIBLE
+ invoker(BOOST_THREAD_RV_REF(invoker) f)
+ : fp_(f.fp_)
+ {}
+ result_type operator()()
+ {
+ return fp_();
+ }
+ };
+#endif
+#endif
+
+ }
+}
+
+#include <boost/thread/detail/variadic_footer.hpp>
+
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/detail/is_convertible.hpp b/src/third_party/boost-1.60.0/boost/thread/detail/is_convertible.hpp
new file mode 100644
index 00000000000..b77620cf179
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/detail/is_convertible.hpp
@@ -0,0 +1,49 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2011-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)
+//
+// See http://www.boost.org/libs/thread for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_THREAD_DETAIL_IS_CONVERTIBLE_HPP
+#define BOOST_THREAD_DETAIL_IS_CONVERTIBLE_HPP
+
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/thread/detail/move.hpp>
+
+namespace boost
+{
+ namespace thread_detail
+ {
+ template <typename T1, typename T2>
+ struct is_convertible : boost::is_convertible<T1,T2> {};
+
+#if defined BOOST_NO_CXX11_RVALUE_REFERENCES
+
+#if defined(BOOST_INTEL_CXX_VERSION) && (BOOST_INTEL_CXX_VERSION <= 1300)
+
+#if defined BOOST_THREAD_USES_MOVE
+ template <typename T1, typename T2>
+ struct is_convertible<
+ rv<T1> &,
+ rv<rv<T2> > &
+ > : false_type {};
+#endif
+
+#elif defined __GNUC__ && (__GNUC__ < 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ <= 4 ))
+
+ template <typename T1, typename T2>
+ struct is_convertible<T1&, T2&> : boost::is_convertible<T1, T2> {};
+#endif
+
+#endif
+ }
+
+} // namespace boost
+
+
+#endif // BOOST_THREAD_DETAIL_MEMORY_HPP
diff --git a/src/third_party/boost-1.60.0/boost/thread/detail/lockable_wrapper.hpp b/src/third_party/boost-1.60.0/boost/thread/detail/lockable_wrapper.hpp
new file mode 100644
index 00000000000..8dc5a6cc786
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/detail/lockable_wrapper.hpp
@@ -0,0 +1,45 @@
+// Distributed under the 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 2012 Vicente J. Botet Escriba
+
+#ifndef BOOST_THREAD_DETAIL_LOCKABLE_WRAPPER_HPP
+#define BOOST_THREAD_DETAIL_LOCKABLE_WRAPPER_HPP
+
+#include <boost/thread/detail/config.hpp>
+
+#if ! defined BOOST_THREAD_NO_CXX11_HDR_INITIALIZER_LIST
+#include <initializer_list>
+#endif
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+
+#if ! defined BOOST_THREAD_NO_CXX11_HDR_INITIALIZER_LIST
+ namespace thread_detail
+ {
+ template <typename Mutex>
+ struct lockable_wrapper
+ {
+ Mutex* m;
+ explicit lockable_wrapper(Mutex& m_) :
+ m(&m_)
+ {}
+ };
+ template <typename Mutex>
+ struct lockable_adopt_wrapper
+ {
+ Mutex* m;
+ explicit lockable_adopt_wrapper(Mutex& m_) :
+ m(&m_)
+ {}
+ };
+ }
+#endif
+
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/detail/log.hpp b/src/third_party/boost-1.60.0/boost/thread/detail/log.hpp
new file mode 100644
index 00000000000..84dcc8cb41f
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/detail/log.hpp
@@ -0,0 +1,83 @@
+// 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)
+
+#ifndef BOOST_THREAD_DETAIL_LOG_HPP
+#define BOOST_THREAD_DETAIL_LOG_HPP
+
+#include <boost/thread/detail/config.hpp>
+#if defined BOOST_THREAD_USES_LOG
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/thread/lock_guard.hpp>
+#if defined BOOST_THREAD_USES_LOG_THREAD_ID
+#include <boost/thread/thread.hpp>
+#endif
+#include <iostream>
+
+namespace boost
+{
+ namespace thread_detail
+ {
+ inline boost::recursive_mutex& terminal_mutex()
+ {
+ static boost::recursive_mutex mtx;
+ return mtx;
+ }
+
+ }
+}
+#if defined BOOST_THREAD_USES_LOG_THREAD_ID
+
+#define BOOST_THREAD_LOG \
+ { \
+ boost::lock_guard<boost::recursive_mutex> _lk_(boost::thread_detail::terminal_mutex()); \
+ std::cout << boost::this_thread::get_id() << " - "<<__FILE__<<"["<<__LINE__<<"] " <<std::dec
+#else
+
+#define BOOST_THREAD_LOG \
+{ \
+ boost::lock_guard<boost::recursive_mutex> _lk_(boost::thread_detail::terminal_mutex()); \
+ std::cout << __FILE__<<"["<<__LINE__<<"] " <<std::dec
+
+#endif
+#define BOOST_THREAD_END_LOG \
+ std::dec << std::endl; \
+ }
+
+#else
+
+namespace boost
+{
+ namespace thread_detail
+ {
+ struct dummy_stream_t
+ {
+ };
+
+ template <typename T>
+ inline dummy_stream_t const& operator<<(dummy_stream_t const& os, T)
+ {
+ return os;
+ }
+
+ inline dummy_stream_t const& operator<<(dummy_stream_t const& os, dummy_stream_t const&)
+ {
+ return os;
+ }
+
+
+ BOOST_CONSTEXPR_OR_CONST dummy_stream_t dummy_stream = {};
+
+ }
+}
+
+#define BOOST_THREAD_LOG if (true) {} else boost::thread_detail::dummy_stream
+#define BOOST_THREAD_END_LOG boost::thread_detail::dummy_stream
+
+#endif
+
+#define BOOST_THREAD_TRACE BOOST_THREAD_LOG << BOOST_THREAD_END_LOG
+
+
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/detail/make_tuple_indices.hpp b/src/third_party/boost-1.60.0/boost/thread/detail/make_tuple_indices.hpp
new file mode 100644
index 00000000000..73d54f11f81
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/detail/make_tuple_indices.hpp
@@ -0,0 +1,224 @@
+// Copyright (C) 2012-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)
+
+// 2013/04 Vicente J. Botet Escriba
+// Provide implementation up to 10 parameters when BOOST_NO_CXX11_VARIADIC_TEMPLATES is defined.
+// 2012/11 Vicente J. Botet Escriba
+// Adapt to boost libc++ implementation
+
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+// The make_tuple_indices C++11 code is based on the one from libcxx.
+//===----------------------------------------------------------------------===//
+
+#ifndef BOOST_THREAD_DETAIL_MAKE_TUPLE_INDICES_HPP
+#define BOOST_THREAD_DETAIL_MAKE_TUPLE_INDICES_HPP
+
+#include <boost/config.hpp>
+#include <boost/static_assert.hpp>
+
+namespace boost
+{
+ namespace detail
+ {
+
+#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ // make_tuple_indices
+
+ template <std::size_t...> struct tuple_indices
+ {};
+
+ template <std::size_t Sp, class IntTuple, std::size_t Ep>
+ struct make_indices_imp;
+
+ template <std::size_t Sp, std::size_t ...Indices, std::size_t Ep>
+ struct make_indices_imp<Sp, tuple_indices<Indices...>, Ep>
+ {
+ typedef typename make_indices_imp<Sp+1, tuple_indices<Indices..., Sp>, Ep>::type type;
+ };
+
+ template <std::size_t Ep, std::size_t ...Indices>
+ struct make_indices_imp<Ep, tuple_indices<Indices...>, Ep>
+ {
+ typedef tuple_indices<Indices...> type;
+ };
+
+ template <std::size_t Ep, std::size_t Sp = 0>
+ struct make_tuple_indices
+ {
+ BOOST_STATIC_ASSERT_MSG(Sp <= Ep, "make_tuple_indices input error");
+ typedef typename make_indices_imp<Sp, tuple_indices<>, Ep>::type type;
+ };
+#else
+
+ // - tuple forward declaration -----------------------------------------------
+ template <
+ std::size_t T0 = 0, std::size_t T1 = 0, std::size_t T2 = 0,
+ std::size_t T3 = 0, std::size_t T4 = 0, std::size_t T5 = 0,
+ std::size_t T6 = 0, std::size_t T7 = 0, std::size_t T8 = 0,
+ std::size_t T9 = 0>
+ class tuple_indices {};
+
+ template <std::size_t Sp, class IntTuple, std::size_t Ep>
+ struct make_indices_imp;
+
+ template <std::size_t Sp, std::size_t Ep>
+ struct make_indices_imp<Sp, tuple_indices<>, Ep>
+ {
+ typedef typename make_indices_imp<Sp+1, tuple_indices<Sp>, Ep>::type type;
+ };
+ template <std::size_t Sp, std::size_t I0, std::size_t Ep>
+ struct make_indices_imp<Sp, tuple_indices<I0>, Ep>
+ {
+ typedef typename make_indices_imp<Sp+1, tuple_indices<I0, Sp>, Ep>::type type;
+ };
+ template <std::size_t Sp, std::size_t I0, std::size_t I1, std::size_t Ep>
+ struct make_indices_imp<Sp, tuple_indices<I0, I1>, Ep>
+ {
+ typedef typename make_indices_imp<Sp+1, tuple_indices<I0, I1, Sp>, Ep>::type type;
+ };
+ template <std::size_t Sp, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t Ep>
+ struct make_indices_imp<Sp, tuple_indices<I0, I1 , I2>, Ep>
+ {
+ typedef typename make_indices_imp<Sp+1, tuple_indices<I0, I1, I2, Sp>, Ep>::type type;
+ };
+ template <std::size_t Sp, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t Ep>
+ struct make_indices_imp<Sp, tuple_indices<I0, I1 , I2, I3>, Ep>
+ {
+ typedef typename make_indices_imp<Sp+1, tuple_indices<I0, I1, I2, I3, Sp>, Ep>::type type;
+ };
+ template <std::size_t Sp, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4, std::size_t Ep>
+ struct make_indices_imp<Sp, tuple_indices<I0, I1 , I2, I3, I4>, Ep>
+ {
+ typedef typename make_indices_imp<Sp+1, tuple_indices<I0, I1, I2, I3, I4, Sp>, Ep>::type type;
+ };
+ template <std::size_t Sp, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4, std::size_t I5, std::size_t Ep>
+ struct make_indices_imp<Sp, tuple_indices<I0, I1 , I2, I3, I4, I5>, Ep>
+ {
+ typedef typename make_indices_imp<Sp+1, tuple_indices<I0, I1, I2, I3, I4, I5, Sp>, Ep>::type type;
+ };
+ template <std::size_t Sp, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4, std::size_t I5
+ , std::size_t I6
+ , std::size_t Ep>
+ struct make_indices_imp<Sp, tuple_indices<I0, I1 , I2, I3, I4, I5, I6>, Ep>
+ {
+ typedef typename make_indices_imp<Sp+1, tuple_indices<I0, I1, I2, I3, I4, I5, I6, Sp>, Ep>::type type;
+ };
+ template <std::size_t Sp, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4, std::size_t I5
+ , std::size_t I6
+ , std::size_t I7
+ , std::size_t Ep>
+ struct make_indices_imp<Sp, tuple_indices<I0, I1 , I2, I3, I4, I5, I6, I7>, Ep>
+ {
+ typedef typename make_indices_imp<Sp+1, tuple_indices<I0, I1, I2, I3, I4, I5, I6, I7, Sp>, Ep>::type type;
+ };
+ template <std::size_t Sp, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4, std::size_t I5
+ , std::size_t I6
+ , std::size_t I7
+ , std::size_t I8
+ , std::size_t Ep>
+ struct make_indices_imp<Sp, tuple_indices<I0, I1 , I2, I3, I4, I5, I6, I7, I8>, Ep>
+ {
+ typedef typename make_indices_imp<Sp+1, tuple_indices<I0, I1, I2, I3, I4, I5, I6, I7, I8, Sp>, Ep>::type type;
+ };
+// template <std::size_t Sp, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4, std::size_t I5
+// , std::size_t I6
+// , std::size_t I7
+// , std::size_t I8
+// , std::size_t I9
+// , std::size_t Ep>
+// struct make_indices_imp<Sp, tuple_indices<I0, I1 , I2, I3, I4, I5, I6, I7, I8, I9>, Ep>
+// {
+// typedef typename make_indices_imp<Sp+1, tuple_indices<I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, Sp>, Ep>::type type;
+// };
+
+ template <std::size_t Ep>
+ struct make_indices_imp<Ep, tuple_indices<>, Ep>
+ {
+ typedef tuple_indices<> type;
+ };
+ template <std::size_t Ep, std::size_t I0>
+ struct make_indices_imp<Ep, tuple_indices<I0>, Ep>
+ {
+ typedef tuple_indices<I0> type;
+ };
+ template <std::size_t Ep, std::size_t I0, std::size_t I1>
+ struct make_indices_imp<Ep, tuple_indices<I0, I1>, Ep>
+ {
+ typedef tuple_indices<I0, I1> type;
+ };
+ template <std::size_t Ep, std::size_t I0, std::size_t I1, std::size_t I2>
+ struct make_indices_imp<Ep, tuple_indices<I0, I1, I2>, Ep>
+ {
+ typedef tuple_indices<I0, I1, I2> type;
+ };
+ template <std::size_t Ep, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3>
+ struct make_indices_imp<Ep, tuple_indices<I0, I1, I2, I3>, Ep>
+ {
+ typedef tuple_indices<I0, I1, I2, I3> type;
+ };
+ template <std::size_t Ep, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4>
+ struct make_indices_imp<Ep, tuple_indices<I0, I1, I2, I3, I4>, Ep>
+ {
+ typedef tuple_indices<I0, I1, I2, I3, I4> type;
+ };
+ template <std::size_t Ep, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4, std::size_t I5>
+ struct make_indices_imp<Ep, tuple_indices<I0, I1, I2, I3, I4, I5>, Ep>
+ {
+ typedef tuple_indices<I0, I1, I2, I3, I4, I5> type;
+ };
+ template <std::size_t Ep, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4, std::size_t I5
+ , std::size_t I6
+ >
+ struct make_indices_imp<Ep, tuple_indices<I0, I1, I2, I3, I4, I5, I6>, Ep>
+ {
+ typedef tuple_indices<I0, I1, I2, I3, I4, I5, I6> type;
+ };
+ template <std::size_t Ep, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4, std::size_t I5
+ , std::size_t I6
+ , std::size_t I7
+ >
+ struct make_indices_imp<Ep, tuple_indices<I0, I1, I2, I3, I4, I5, I6, I7>, Ep>
+ {
+ typedef tuple_indices<I0, I1, I2, I3, I4, I5, I6, I7> type;
+ };
+ template <std::size_t Ep, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4, std::size_t I5
+ , std::size_t I6
+ , std::size_t I7
+ , std::size_t I8
+ >
+ struct make_indices_imp<Ep, tuple_indices<I0, I1, I2, I3, I4, I5, I6, I7, I8>, Ep>
+ {
+ typedef tuple_indices<I0, I1, I2, I3, I4, I5, I6, I7, I8> type;
+ };
+
+ template <std::size_t Ep, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4, std::size_t I5
+ , std::size_t I6
+ , std::size_t I7
+ , std::size_t I8
+ , std::size_t I9
+ >
+ struct make_indices_imp<Ep, tuple_indices<I0, I1, I2, I3, I4, I5, I6, I7, I8, I9>, Ep>
+ {
+ typedef tuple_indices<I0, I1, I2, I3, I4, I5, I6, I7, I8, I9> type;
+ };
+
+ template <std::size_t Ep, std::size_t Sp = 0>
+ struct make_tuple_indices
+ {
+ BOOST_STATIC_ASSERT_MSG(Sp <= Ep, "make_tuple_indices input error");
+ typedef typename make_indices_imp<Sp, tuple_indices<>, Ep>::type type;
+ };
+
+#endif
+ }
+}
+
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/detail/memory.hpp b/src/third_party/boost-1.60.0/boost/thread/detail/memory.hpp
new file mode 100644
index 00000000000..51ce84f40bc
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/detail/memory.hpp
@@ -0,0 +1,48 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2011-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)
+//
+// See http://www.boost.org/libs/thread for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_THREAD_DETAIL_MEMORY_HPP
+#define BOOST_THREAD_DETAIL_MEMORY_HPP
+
+#include <boost/config.hpp>
+
+#include <boost/thread/csbl/memory/pointer_traits.hpp>
+#include <boost/thread/csbl/memory/allocator_arg.hpp>
+#include <boost/thread/csbl/memory/allocator_traits.hpp>
+#include <boost/thread/csbl/memory/scoped_allocator.hpp>
+
+namespace boost
+{
+ namespace thread_detail
+ {
+ template <class _Alloc>
+ class allocator_destructor
+ {
+ typedef csbl::allocator_traits<_Alloc> alloc_traits;
+ public:
+ typedef typename alloc_traits::pointer pointer;
+ typedef typename alloc_traits::size_type size_type;
+ private:
+ _Alloc alloc_;
+ size_type s_;
+ public:
+ allocator_destructor(_Alloc& a, size_type s)BOOST_NOEXCEPT
+ : alloc_(a), s_(s)
+ {}
+ void operator()(pointer p)BOOST_NOEXCEPT
+ {
+ alloc_traits::destroy(alloc_, p);
+ alloc_traits::deallocate(alloc_, p, s_);
+ }
+ };
+ } //namespace thread_detail
+}
+#endif // BOOST_THREAD_DETAIL_MEMORY_HPP
diff --git a/src/third_party/boost-1.60.0/boost/thread/detail/move.hpp b/src/third_party/boost-1.60.0/boost/thread/detail/move.hpp
new file mode 100644
index 00000000000..26e4f9dc6dd
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/detail/move.hpp
@@ -0,0 +1,374 @@
+// Distributed under the 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 2007-8 Anthony Williams
+// (C) Copyright 2011-2012 Vicente J. Botet Escriba
+
+#ifndef BOOST_THREAD_MOVE_HPP
+#define BOOST_THREAD_MOVE_HPP
+
+#include <boost/thread/detail/config.hpp>
+#ifndef BOOST_NO_SFINAE
+#include <boost/core/enable_if.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/decay.hpp>
+#include <boost/type_traits/conditional.hpp>
+#include <boost/type_traits/remove_extent.hpp>
+#include <boost/type_traits/is_array.hpp>
+#include <boost/type_traits/is_function.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/add_pointer.hpp>
+#include <boost/type_traits/decay.hpp>
+#endif
+
+#include <boost/thread/detail/delete.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/move/traits.hpp>
+#include <boost/config/abi_prefix.hpp>
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+#include <type_traits>
+#endif
+namespace boost
+{
+
+ namespace detail
+ {
+ template <typename T>
+ struct enable_move_utility_emulation_dummy_specialization;
+ template<typename T>
+ struct thread_move_t
+ {
+ T& t;
+ explicit thread_move_t(T& t_):
+ t(t_)
+ {}
+
+ T& operator*() const
+ {
+ return t;
+ }
+
+ T* operator->() const
+ {
+ return &t;
+ }
+ private:
+ void operator=(thread_move_t&);
+ };
+ }
+
+#if !defined BOOST_THREAD_USES_MOVE
+
+#ifndef BOOST_NO_SFINAE
+ template<typename T>
+ typename enable_if<boost::is_convertible<T&,boost::detail::thread_move_t<T> >, boost::detail::thread_move_t<T> >::type move(T& t)
+ {
+ return boost::detail::thread_move_t<T>(t);
+ }
+#endif
+
+ template<typename T>
+ boost::detail::thread_move_t<T> move(boost::detail::thread_move_t<T> t)
+ {
+ return t;
+ }
+
+#endif //#if !defined BOOST_THREAD_USES_MOVE
+}
+
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+
+#define BOOST_THREAD_COPY_ASSIGN_REF(TYPE) BOOST_COPY_ASSIGN_REF(TYPE)
+#define BOOST_THREAD_RV_REF(TYPE) BOOST_RV_REF(TYPE)
+#define BOOST_THREAD_RV_REF_2_TEMPL_ARGS(TYPE) BOOST_RV_REF_2_TEMPL_ARGS(TYPE)
+#define BOOST_THREAD_RV_REF_BEG BOOST_RV_REF_BEG
+#define BOOST_THREAD_RV_REF_END BOOST_RV_REF_END
+#define BOOST_THREAD_RV(V) V
+#define BOOST_THREAD_MAKE_RV_REF(RVALUE) RVALUE
+#define BOOST_THREAD_FWD_REF(TYPE) BOOST_FWD_REF(TYPE)
+#define BOOST_THREAD_DCL_MOVABLE(TYPE)
+#define BOOST_THREAD_DCL_MOVABLE_BEG(T) \
+ namespace detail { \
+ template <typename T> \
+ struct enable_move_utility_emulation_dummy_specialization<
+
+#define BOOST_THREAD_DCL_MOVABLE_BEG2(T1, T2) \
+ namespace detail { \
+ template <typename T1, typename T2> \
+ struct enable_move_utility_emulation_dummy_specialization<
+
+#define BOOST_THREAD_DCL_MOVABLE_END > \
+ : integral_constant<bool, false> \
+ {}; \
+ }
+
+#elif ! defined BOOST_NO_CXX11_RVALUE_REFERENCES && defined BOOST_MSVC
+
+#define BOOST_THREAD_COPY_ASSIGN_REF(TYPE) BOOST_COPY_ASSIGN_REF(TYPE)
+#define BOOST_THREAD_RV_REF(TYPE) BOOST_RV_REF(TYPE)
+#define BOOST_THREAD_RV_REF_2_TEMPL_ARGS(TYPE) BOOST_RV_REF_2_TEMPL_ARGS(TYPE)
+#define BOOST_THREAD_RV_REF_BEG BOOST_RV_REF_BEG
+#define BOOST_THREAD_RV_REF_END BOOST_RV_REF_END
+#define BOOST_THREAD_RV(V) V
+#define BOOST_THREAD_MAKE_RV_REF(RVALUE) RVALUE
+#define BOOST_THREAD_FWD_REF(TYPE) BOOST_FWD_REF(TYPE)
+#define BOOST_THREAD_DCL_MOVABLE(TYPE)
+#define BOOST_THREAD_DCL_MOVABLE_BEG(T) \
+ namespace detail { \
+ template <typename T> \
+ struct enable_move_utility_emulation_dummy_specialization<
+
+#define BOOST_THREAD_DCL_MOVABLE_BEG2(T1, T2) \
+ namespace detail { \
+ template <typename T1, typename T2> \
+ struct enable_move_utility_emulation_dummy_specialization<
+
+#define BOOST_THREAD_DCL_MOVABLE_END > \
+ : integral_constant<bool, false> \
+ {}; \
+ }
+
+#else
+
+#if defined BOOST_THREAD_USES_MOVE
+#define BOOST_THREAD_COPY_ASSIGN_REF(TYPE) BOOST_COPY_ASSIGN_REF(TYPE)
+#define BOOST_THREAD_RV_REF(TYPE) BOOST_RV_REF(TYPE)
+#define BOOST_THREAD_RV_REF_2_TEMPL_ARGS(TYPE) BOOST_RV_REF_2_TEMPL_ARGS(TYPE)
+#define BOOST_THREAD_RV_REF_BEG BOOST_RV_REF_BEG
+#define BOOST_THREAD_RV_REF_END BOOST_RV_REF_END
+#define BOOST_THREAD_RV(V) V
+#define BOOST_THREAD_FWD_REF(TYPE) BOOST_FWD_REF(TYPE)
+#define BOOST_THREAD_DCL_MOVABLE(TYPE)
+#define BOOST_THREAD_DCL_MOVABLE_BEG(T) \
+ namespace detail { \
+ template <typename T> \
+ struct enable_move_utility_emulation_dummy_specialization<
+
+#define BOOST_THREAD_DCL_MOVABLE_BEG2(T1, T2) \
+ namespace detail { \
+ template <typename T1, typename T2> \
+ struct enable_move_utility_emulation_dummy_specialization<
+
+#define BOOST_THREAD_DCL_MOVABLE_END > \
+ : integral_constant<bool, false> \
+ {}; \
+ }
+
+#else
+
+#define BOOST_THREAD_COPY_ASSIGN_REF(TYPE) const TYPE&
+#define BOOST_THREAD_RV_REF(TYPE) boost::detail::thread_move_t< TYPE >
+#define BOOST_THREAD_RV_REF_BEG boost::detail::thread_move_t<
+#define BOOST_THREAD_RV_REF_END >
+#define BOOST_THREAD_RV(V) (*V)
+#define BOOST_THREAD_FWD_REF(TYPE) BOOST_FWD_REF(TYPE)
+
+#define BOOST_THREAD_DCL_MOVABLE(TYPE) \
+template <> \
+struct enable_move_utility_emulation< TYPE > \
+{ \
+ static const bool value = false; \
+};
+
+#define BOOST_THREAD_DCL_MOVABLE_BEG(T) \
+template <typename T> \
+struct enable_move_utility_emulation<
+
+#define BOOST_THREAD_DCL_MOVABLE_BEG2(T1, T2) \
+template <typename T1, typename T2> \
+struct enable_move_utility_emulation<
+
+#define BOOST_THREAD_DCL_MOVABLE_END > \
+{ \
+ static const bool value = false; \
+};
+
+#endif
+
+namespace boost
+{
+namespace detail
+{
+ template <typename T>
+ BOOST_THREAD_RV_REF(typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type)
+ make_rv_ref(T v) BOOST_NOEXCEPT
+ {
+ return (BOOST_THREAD_RV_REF(typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type))(v);
+ }
+// template <typename T>
+// BOOST_THREAD_RV_REF(typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type)
+// make_rv_ref(T &v) BOOST_NOEXCEPT
+// {
+// return (BOOST_THREAD_RV_REF(typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type))(v);
+// }
+// template <typename T>
+// const BOOST_THREAD_RV_REF(typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type)
+// make_rv_ref(T const&v) BOOST_NOEXCEPT
+// {
+// return (const BOOST_THREAD_RV_REF(typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type))(v);
+// }
+}
+}
+
+#define BOOST_THREAD_MAKE_RV_REF(RVALUE) RVALUE.move()
+//#define BOOST_THREAD_MAKE_RV_REF(RVALUE) boost::detail::make_rv_ref(RVALUE)
+#endif
+
+
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+
+#define BOOST_THREAD_MOVABLE(TYPE)
+
+#define BOOST_THREAD_COPYABLE(TYPE)
+
+#else
+
+#if defined BOOST_THREAD_USES_MOVE
+
+#define BOOST_THREAD_MOVABLE(TYPE) \
+ ::boost::rv<TYPE>& move() BOOST_NOEXCEPT \
+ { \
+ return *static_cast< ::boost::rv<TYPE>* >(this); \
+ } \
+ const ::boost::rv<TYPE>& move() const BOOST_NOEXCEPT \
+ { \
+ return *static_cast<const ::boost::rv<TYPE>* >(this); \
+ } \
+ operator ::boost::rv<TYPE>&() \
+ { \
+ return *static_cast< ::boost::rv<TYPE>* >(this); \
+ } \
+ operator const ::boost::rv<TYPE>&() const \
+ { \
+ return *static_cast<const ::boost::rv<TYPE>* >(this); \
+ }\
+
+#define BOOST_THREAD_COPYABLE(TYPE) \
+ TYPE& operator=(TYPE &t)\
+ { this->operator=(static_cast<const ::boost::rv<TYPE> &>(const_cast<const TYPE &>(t))); return *this;}
+
+
+#else
+
+#define BOOST_THREAD_MOVABLE(TYPE) \
+ operator ::boost::detail::thread_move_t<TYPE>() BOOST_NOEXCEPT \
+ { \
+ return move(); \
+ } \
+ ::boost::detail::thread_move_t<TYPE> move() BOOST_NOEXCEPT \
+ { \
+ ::boost::detail::thread_move_t<TYPE> x(*this); \
+ return x; \
+ } \
+
+#define BOOST_THREAD_COPYABLE(TYPE)
+
+#endif
+#endif
+
+#define BOOST_THREAD_MOVABLE_ONLY(TYPE) \
+ BOOST_THREAD_NO_COPYABLE(TYPE) \
+ BOOST_THREAD_MOVABLE(TYPE) \
+ typedef int boost_move_no_copy_constructor_or_assign; \
+
+
+#define BOOST_THREAD_COPYABLE_AND_MOVABLE(TYPE) \
+ BOOST_THREAD_COPYABLE(TYPE) \
+ BOOST_THREAD_MOVABLE(TYPE) \
+
+
+
+namespace boost
+{
+ namespace thread_detail
+ {
+
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+#elif defined BOOST_THREAD_USES_MOVE
+ template <class T>
+ struct is_rv
+ : ::boost::move_detail::is_rv<T>
+ {};
+
+#else
+ template <class T>
+ struct is_rv
+ : ::boost::integral_constant<bool, false>
+ {};
+
+ template <class T>
+ struct is_rv< ::boost::detail::thread_move_t<T> >
+ : ::boost::integral_constant<bool, true>
+ {};
+
+ template <class T>
+ struct is_rv< const ::boost::detail::thread_move_t<T> >
+ : ::boost::integral_constant<bool, true>
+ {};
+#endif
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ template <class Tp>
+ struct remove_reference : boost::remove_reference<Tp> {};
+ template <class Tp>
+ struct decay : boost::decay<Tp> {};
+#else
+ template <class Tp>
+ struct remove_reference
+ {
+ typedef Tp type;
+ };
+ template <class Tp>
+ struct remove_reference<Tp&>
+ {
+ typedef Tp type;
+ };
+ template <class Tp>
+ struct remove_reference< rv<Tp> > {
+ typedef Tp type;
+ };
+
+ template <class Tp>
+ struct decay
+ {
+ private:
+ typedef typename boost::move_detail::remove_rvalue_reference<Tp>::type Up0;
+ typedef typename boost::remove_reference<Up0>::type Up;
+ public:
+ typedef typename conditional
+ <
+ is_array<Up>::value,
+ typename remove_extent<Up>::type*,
+ typename conditional
+ <
+ is_function<Up>::value,
+ typename add_pointer<Up>::type,
+ typename remove_cv<Up>::type
+ >::type
+ >::type type;
+ };
+#endif
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ template <class T>
+ typename decay<T>::type
+ decay_copy(T&& t)
+ {
+ return boost::forward<T>(t);
+ }
+#else
+ template <class T>
+ typename decay<T>::type
+ decay_copy(BOOST_THREAD_FWD_REF(T) t)
+ {
+ return boost::forward<T>(t);
+ }
+#endif
+ }
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/detail/nullary_function.hpp b/src/third_party/boost-1.60.0/boost/thread/detail/nullary_function.hpp
new file mode 100644
index 00000000000..b3989cf682e
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/detail/nullary_function.hpp
@@ -0,0 +1,234 @@
+// 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)
+//
+// 2013/09 Vicente J. Botet Escriba
+// Adapt to boost from CCIA C++11 implementation
+// Make use of Boost.Move
+
+#ifndef BOOST_THREAD_DETAIL_NULLARY_FUNCTION_HPP
+#define BOOST_THREAD_DETAIL_NULLARY_FUNCTION_HPP
+
+#include <boost/config.hpp>
+#include <boost/thread/detail/memory.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/csbl/memory/shared_ptr.hpp>
+#include <boost/type_traits/decay.hpp>
+
+namespace boost
+{
+ namespace detail
+ {
+
+ template <typename F>
+ class nullary_function;
+ template <>
+ class nullary_function<void()>
+ {
+ struct impl_base
+ {
+ virtual void call()=0;
+ virtual ~impl_base()
+ {
+ }
+ };
+ csbl::shared_ptr<impl_base> impl;
+ template <typename F>
+ struct impl_type: impl_base
+ {
+ F f;
+#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
+ impl_type(F &f_)
+ : f(f_)
+ {}
+#endif
+ impl_type(BOOST_THREAD_RV_REF(F) f_)
+ : f(boost::move(f_))
+ {}
+
+ void call()
+ {
+ f();
+ }
+ };
+ struct impl_type_ptr: impl_base
+ {
+ void (*f)();
+ impl_type_ptr(void (*f_)())
+ : f(f_)
+ {}
+ void call()
+ {
+ f();
+ }
+ };
+ public:
+ BOOST_THREAD_COPYABLE_AND_MOVABLE(nullary_function)
+
+ explicit nullary_function(void (*f)()):
+ impl(new impl_type_ptr(f))
+ {}
+
+#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
+ template<typename F>
+ explicit nullary_function(F& f):
+ impl(new impl_type<F>(f))
+ {}
+#endif
+ template<typename F>
+ nullary_function(BOOST_THREAD_RV_REF(F) f):
+ impl(new impl_type<typename decay<F>::type>(thread_detail::decay_copy(boost::forward<F>(f))))
+ {}
+
+ nullary_function()
+ : impl()
+ {
+ }
+ nullary_function(nullary_function const& other) BOOST_NOEXCEPT :
+ impl(other.impl)
+ {
+ }
+ nullary_function(BOOST_THREAD_RV_REF(nullary_function) other) BOOST_NOEXCEPT :
+#if defined BOOST_NO_CXX11_SMART_PTR
+ impl(BOOST_THREAD_RV(other).impl)
+ {
+ BOOST_THREAD_RV(other).impl.reset();
+ }
+#else
+ impl(boost::move(other.impl))
+ {
+ }
+#endif
+ ~nullary_function()
+ {
+ }
+
+ nullary_function& operator=(BOOST_THREAD_COPY_ASSIGN_REF(nullary_function) other) BOOST_NOEXCEPT
+ {
+ impl=other.impl;
+ return *this;
+ }
+ nullary_function& operator=(BOOST_THREAD_RV_REF(nullary_function) other) BOOST_NOEXCEPT
+ {
+#if defined BOOST_NO_CXX11_SMART_PTR
+ impl=BOOST_THREAD_RV(other).impl;
+ BOOST_THREAD_RV(other).impl.reset();
+#else
+ impl = boost::move(other.impl);
+#endif
+ return *this;
+ }
+
+
+ void operator()()
+ { if (impl) impl->call();}
+
+ };
+
+ template <typename R>
+ class nullary_function<R()>
+ {
+ struct impl_base
+ {
+ virtual R call()=0;
+ virtual ~impl_base()
+ {
+ }
+ };
+ csbl::shared_ptr<impl_base> impl;
+ template <typename F>
+ struct impl_type: impl_base
+ {
+ F f;
+#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
+ impl_type(F &f_)
+ : f(f_)
+ {}
+#endif
+ impl_type(BOOST_THREAD_RV_REF(F) f_)
+ : f(boost::move(f_))
+ {}
+
+ R call()
+ {
+ return f();
+ }
+ };
+ struct impl_type_ptr: impl_base
+ {
+ R (*f)();
+ impl_type_ptr(R (*f_)())
+ : f(f_)
+ {}
+
+ R call()
+ {
+ return f();
+ }
+ };
+ public:
+ BOOST_THREAD_COPYABLE_AND_MOVABLE(nullary_function)
+
+ nullary_function(R (*f)()):
+ impl(new impl_type_ptr(f))
+ {}
+#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
+ template<typename F>
+ nullary_function(F& f):
+ impl(new impl_type<F>(f))
+ {}
+#endif
+ template<typename F>
+ nullary_function(BOOST_THREAD_RV_REF(F) f):
+ impl(new impl_type<typename decay<F>::type>(thread_detail::decay_copy(boost::forward<F>(f))))
+ {}
+
+ nullary_function(nullary_function const& other) BOOST_NOEXCEPT :
+ impl(other.impl)
+ {
+ }
+ nullary_function(BOOST_THREAD_RV_REF(nullary_function) other) BOOST_NOEXCEPT :
+#if defined BOOST_NO_CXX11_SMART_PTR
+ impl(BOOST_THREAD_RV(other).impl)
+ {
+ BOOST_THREAD_RV(other).impl.reset();
+ }
+#else
+ impl(boost::move(other.impl))
+ {
+ }
+#endif
+ nullary_function()
+ : impl()
+ {
+ }
+ ~nullary_function()
+ {
+ }
+
+ nullary_function& operator=(BOOST_THREAD_COPY_ASSIGN_REF(nullary_function) other) BOOST_NOEXCEPT
+ {
+ impl=other.impl;
+ return *this;
+ }
+ nullary_function& operator=(BOOST_THREAD_RV_REF(nullary_function) other) BOOST_NOEXCEPT
+ {
+#if defined BOOST_NO_CXX11_SMART_PTR
+ impl=BOOST_THREAD_RV(other).impl;
+ BOOST_THREAD_RV(other).impl.reset();
+#else
+ impl = boost::move(other.impl);
+#endif
+ return *this;
+ }
+
+ R operator()()
+ { if (impl) return impl->call(); else return R();}
+
+ };
+ }
+ BOOST_THREAD_DCL_MOVABLE_BEG(F) detail::nullary_function<F> BOOST_THREAD_DCL_MOVABLE_END
+}
+
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/detail/platform.hpp b/src/third_party/boost-1.60.0/boost/thread/detail/platform.hpp
new file mode 100644
index 00000000000..1f33b1a67ae
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/detail/platform.hpp
@@ -0,0 +1,73 @@
+// Copyright 2006 Roland Schwarz.
+// (C) Copyright 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)
+//
+// This work is a reimplementation along the design and ideas
+// of William E. Kempf.
+
+#ifndef BOOST_THREAD_RS06040501_HPP
+#define BOOST_THREAD_RS06040501_HPP
+
+// fetch compiler and platform configuration
+#include <boost/config.hpp>
+
+// insist on threading support being available:
+#include <boost/config/requires_threads.hpp>
+
+// choose platform
+#if defined(linux) || defined(__linux) || defined(__linux__)
+# define BOOST_THREAD_LINUX
+//# define BOOST_THREAD_WAIT_BUG boost::posix_time::microseconds(100000)
+#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
+# define BOOST_THREAD_BSD
+#elif defined(sun) || defined(__sun)
+# define BOOST_THREAD_SOLARIS
+#elif defined(__sgi)
+# define BOOST_THREAD_IRIX
+#elif defined(__hpux)
+# define BOOST_THREAD_HPUX
+#elif defined(__CYGWIN__)
+# define BOOST_THREAD_CYGWIN
+#elif (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) && !defined(BOOST_DISABLE_WIN32)
+# define BOOST_THREAD_WIN32
+#elif defined(__BEOS__)
+# define BOOST_THREAD_BEOS
+#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
+# define BOOST_THREAD_MACOS
+//# define BOOST_THREAD_WAIT_BUG boost::posix_time::microseconds(1000)
+#elif defined(__IBMCPP__) || defined(_AIX)
+# define BOOST_THREAD_AIX
+#elif defined(__amigaos__)
+# define BOOST_THREAD_AMIGAOS
+#elif defined(__QNXNTO__)
+# define BOOST_THREAD_QNXNTO
+#elif defined(unix) || defined(__unix) || defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE)
+# if defined(BOOST_HAS_PTHREADS) && !defined(BOOST_THREAD_POSIX)
+# define BOOST_THREAD_POSIX
+# endif
+#endif
+
+// For every supported platform add a new entry into the dispatch table below.
+// BOOST_THREAD_POSIX is tested first, so on platforms where posix and native
+// threading is available, the user may choose, by defining BOOST_THREAD_POSIX
+// in her source. If a platform is known to support pthreads and no native
+// port of boost_thread is available just specify "pthread" in the
+// dispatcher table. If there is no entry for a platform but pthreads is
+// available on the platform, pthread is choosen as default. If nothing is
+// available the preprocessor will fail with a diagnostic message.
+
+#if defined(BOOST_THREAD_POSIX)
+# define BOOST_THREAD_PLATFORM_PTHREAD
+#else
+# if defined(BOOST_THREAD_WIN32)
+# define BOOST_THREAD_PLATFORM_WIN32
+# elif defined(BOOST_HAS_PTHREADS)
+# define BOOST_THREAD_PLATFORM_PTHREAD
+# else
+# error "Sorry, no boost threads are available for this platform."
+# endif
+#endif
+
+#endif // BOOST_THREAD_RS06040501_HPP
diff --git a/src/third_party/boost-1.60.0/boost/thread/detail/singleton.hpp b/src/third_party/boost-1.60.0/boost/thread/detail/singleton.hpp
new file mode 100644
index 00000000000..a20a42908d2
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/detail/singleton.hpp
@@ -0,0 +1,59 @@
+// Copyright (C) 2001-2003
+// Mac Murrett
+//
+// Distributed under the 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 http://www.boost.org for most recent version including documentation.
+
+#ifndef BOOST_SINGLETON_MJM012402_HPP
+#define BOOST_SINGLETON_MJM012402_HPP
+
+#include <boost/thread/detail/config.hpp>
+
+namespace boost {
+namespace detail {
+namespace thread {
+
+// class singleton has the same goal as all singletons: create one instance of
+// a class on demand, then dish it out as requested.
+
+template <class T>
+class singleton : private T
+{
+private:
+ singleton();
+ ~singleton();
+
+public:
+ static T &instance();
+};
+
+
+template <class T>
+inline singleton<T>::singleton()
+{
+ /* no-op */
+}
+
+template <class T>
+inline singleton<T>::~singleton()
+{
+ /* no-op */
+}
+
+template <class T>
+/*static*/ T &singleton<T>::instance()
+{
+ // function-local static to force this to work correctly at static
+ // initialization time.
+ static singleton<T> s_oT;
+ return(s_oT);
+}
+
+} // namespace thread
+} // namespace detail
+} // namespace boost
+
+#endif // BOOST_SINGLETON_MJM012402_HPP
diff --git a/src/third_party/boost-1.60.0/boost/thread/detail/thread.hpp b/src/third_party/boost-1.60.0/boost/thread/detail/thread.hpp
new file mode 100644
index 00000000000..9e7e8b8f5e9
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/detail/thread.hpp
@@ -0,0 +1,873 @@
+#ifndef BOOST_THREAD_THREAD_COMMON_HPP
+#define BOOST_THREAD_THREAD_COMMON_HPP
+// Distributed under the 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 2007-2010 Anthony Williams
+// (C) Copyright 2011-2012 Vicente J. Botet Escriba
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/predef/platform.h>
+
+#include <boost/thread/exceptions.hpp>
+#ifndef BOOST_NO_IOSTREAM
+#include <ostream>
+#endif
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/mutex.hpp>
+#if defined BOOST_THREAD_USES_DATETIME
+#include <boost/thread/xtime.hpp>
+#endif
+#include <boost/thread/detail/thread_heap_alloc.hpp>
+#include <boost/thread/detail/make_tuple_indices.hpp>
+#include <boost/thread/detail/invoke.hpp>
+#include <boost/thread/detail/is_convertible.hpp>
+#include <boost/assert.hpp>
+#include <list>
+#include <algorithm>
+#include <boost/core/ref.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/bind.hpp>
+#include <stdlib.h>
+#include <memory>
+#include <boost/core/enable_if.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/io/ios_state.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/decay.hpp>
+#include <boost/functional/hash.hpp>
+#ifdef BOOST_THREAD_USES_CHRONO
+#include <boost/chrono/system_clocks.hpp>
+#include <boost/chrono/ceil.hpp>
+#endif
+
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+#include <tuple>
+#endif
+#include <boost/config/abi_prefix.hpp>
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4251)
+#endif
+
+namespace boost
+{
+
+ namespace detail
+ {
+
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+
+ template<typename F, class ...ArgTypes>
+ class thread_data:
+ public detail::thread_data_base
+ {
+ public:
+ BOOST_THREAD_NO_COPYABLE(thread_data)
+ thread_data(BOOST_THREAD_RV_REF(F) f_, BOOST_THREAD_RV_REF(ArgTypes)... args_):
+ fp(boost::forward<F>(f_), boost::forward<ArgTypes>(args_)...)
+ {}
+ template <std::size_t ...Indices>
+ void run2(tuple_indices<Indices...>)
+ {
+
+ detail::invoke(std::move(std::get<0>(fp)), std::move(std::get<Indices>(fp))...);
+ }
+ void run()
+ {
+ typedef typename make_tuple_indices<std::tuple_size<std::tuple<F, ArgTypes...> >::value, 1>::type index_type;
+
+ run2(index_type());
+ }
+
+ private:
+ std::tuple<typename decay<F>::type, typename decay<ArgTypes>::type...> fp;
+ };
+#else // defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+
+ template<typename F>
+ class thread_data:
+ public detail::thread_data_base
+ {
+ public:
+ BOOST_THREAD_NO_COPYABLE(thread_data)
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ thread_data(BOOST_THREAD_RV_REF(F) f_):
+ f(boost::forward<F>(f_))
+ {}
+// This overloading must be removed if we want the packaged_task's tests to pass.
+// thread_data(F& f_):
+// f(f_)
+// {}
+#else
+
+ thread_data(BOOST_THREAD_RV_REF(F) f_):
+ f(f_)
+ {}
+ thread_data(F f_):
+ f(f_)
+ {}
+#endif
+ //thread_data() {}
+
+ void run()
+ {
+ f();
+ }
+
+ private:
+ F f;
+ };
+
+ template<typename F>
+ class thread_data<boost::reference_wrapper<F> >:
+ public detail::thread_data_base
+ {
+ private:
+ F& f;
+ public:
+ BOOST_THREAD_NO_COPYABLE(thread_data)
+ thread_data(boost::reference_wrapper<F> f_):
+ f(f_)
+ {}
+ void run()
+ {
+ f();
+ }
+ };
+
+ template<typename F>
+ class thread_data<const boost::reference_wrapper<F> >:
+ public detail::thread_data_base
+ {
+ private:
+ F& f;
+ public:
+ BOOST_THREAD_NO_COPYABLE(thread_data)
+ thread_data(const boost::reference_wrapper<F> f_):
+ f(f_)
+ {}
+ void run()
+ {
+ f();
+ }
+ };
+#endif
+ }
+
+ class BOOST_THREAD_DECL thread
+ {
+ public:
+ typedef thread_attributes attributes;
+
+ BOOST_THREAD_MOVABLE_ONLY(thread)
+ private:
+
+ struct dummy;
+
+ void release_handle();
+
+ detail::thread_data_ptr thread_info;
+
+ private:
+ bool start_thread_noexcept();
+ bool start_thread_noexcept(const attributes& attr);
+ void start_thread()
+ {
+ if (!start_thread_noexcept())
+ {
+ boost::throw_exception(thread_resource_error());
+ }
+ }
+ void start_thread(const attributes& attr)
+ {
+ if (!start_thread_noexcept(attr))
+ {
+ boost::throw_exception(thread_resource_error());
+ }
+ }
+
+ explicit thread(detail::thread_data_ptr data);
+
+ detail::thread_data_ptr get_thread_info BOOST_PREVENT_MACRO_SUBSTITUTION () const;
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ template<typename F, class ...ArgTypes>
+ static inline detail::thread_data_ptr make_thread_info(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_RV_REF(ArgTypes)... args)
+ {
+ return detail::thread_data_ptr(detail::heap_new<
+ detail::thread_data<typename boost::remove_reference<F>::type, ArgTypes...>
+ >(
+ boost::forward<F>(f), boost::forward<ArgTypes>(args)...
+ )
+ );
+ }
+#else
+ template<typename F>
+ static inline detail::thread_data_ptr make_thread_info(BOOST_THREAD_RV_REF(F) f)
+ {
+ return detail::thread_data_ptr(detail::heap_new<detail::thread_data<typename boost::remove_reference<F>::type> >(
+ boost::forward<F>(f)));
+ }
+#endif
+ static inline detail::thread_data_ptr make_thread_info(void (*f)())
+ {
+ return detail::thread_data_ptr(detail::heap_new<detail::thread_data<void(*)()> >(
+ boost::forward<void(*)()>(f)));
+ }
+#else
+ template<typename F>
+ static inline detail::thread_data_ptr make_thread_info(F f
+ , typename disable_if_c<
+ //boost::thread_detail::is_convertible<F&,BOOST_THREAD_RV_REF(F)>::value ||
+ is_same<typename decay<F>::type, thread>::value,
+ dummy* >::type=0
+ )
+ {
+ return detail::thread_data_ptr(detail::heap_new<detail::thread_data<F> >(f));
+ }
+ template<typename F>
+ static inline detail::thread_data_ptr make_thread_info(BOOST_THREAD_RV_REF(F) f)
+ {
+ return detail::thread_data_ptr(detail::heap_new<detail::thread_data<F> >(f));
+ }
+
+#endif
+ public:
+#if 0 // This should not be needed anymore. Use instead BOOST_THREAD_MAKE_RV_REF.
+#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
+ thread(const volatile thread&);
+#endif
+#endif
+ thread() BOOST_NOEXCEPT;
+ ~thread()
+ {
+
+ #if defined BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE
+ if (joinable()) {
+ std::terminate();
+ }
+ #else
+ detach();
+ #endif
+ }
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ template <
+ class F
+ >
+ explicit thread(BOOST_THREAD_RV_REF(F) f
+ //, typename disable_if<is_same<typename decay<F>::type, thread>, dummy* >::type=0
+ ):
+ thread_info(make_thread_info(thread_detail::decay_copy(boost::forward<F>(f))))
+ {
+ start_thread();
+ }
+ template <
+ class F
+ >
+ thread(attributes const& attrs, BOOST_THREAD_RV_REF(F) f):
+ thread_info(make_thread_info(thread_detail::decay_copy(boost::forward<F>(f))))
+ {
+ start_thread(attrs);
+ }
+
+#else
+#ifdef BOOST_NO_SFINAE
+ template <class F>
+ explicit thread(F f):
+ thread_info(make_thread_info(f))
+ {
+ start_thread();
+ }
+ template <class F>
+ thread(attributes const& attrs, F f):
+ thread_info(make_thread_info(f))
+ {
+ start_thread(attrs);
+ }
+#else
+ template <class F>
+ explicit thread(F f
+ , typename disable_if_c<
+ boost::thread_detail::is_rv<F>::value // todo ass a thread_detail::is_rv
+ //boost::thread_detail::is_convertible<F&,BOOST_THREAD_RV_REF(F)>::value
+ //|| is_same<typename decay<F>::type, thread>::value
+ , dummy* >::type=0
+ ):
+ thread_info(make_thread_info(f))
+ {
+ start_thread();
+ }
+ template <class F>
+ thread(attributes const& attrs, F f
+ , typename disable_if<boost::thread_detail::is_rv<F>, dummy* >::type=0
+ //, typename disable_if<boost::thread_detail::is_convertible<F&,BOOST_THREAD_RV_REF(F) >, dummy* >::type=0
+ ):
+ thread_info(make_thread_info(f))
+ {
+ start_thread(attrs);
+ }
+#endif
+ template <class F>
+ explicit thread(BOOST_THREAD_RV_REF(F) f
+ , typename disable_if<is_same<typename decay<F>::type, thread>, dummy* >::type=0
+ ):
+#ifdef BOOST_THREAD_USES_MOVE
+ thread_info(make_thread_info(boost::move<F>(f))) // todo : Add forward
+#else
+ thread_info(make_thread_info(f)) // todo : Add forward
+#endif
+ {
+ start_thread();
+ }
+
+ template <class F>
+ thread(attributes const& attrs, BOOST_THREAD_RV_REF(F) f):
+#ifdef BOOST_THREAD_USES_MOVE
+ thread_info(make_thread_info(boost::move<F>(f))) // todo : Add forward
+#else
+ thread_info(make_thread_info(f)) // todo : Add forward
+#endif
+ {
+ start_thread(attrs);
+ }
+#endif
+ thread(BOOST_THREAD_RV_REF(thread) x) BOOST_NOEXCEPT
+ {
+ thread_info=BOOST_THREAD_RV(x).thread_info;
+ BOOST_THREAD_RV(x).thread_info.reset();
+ }
+#if 0 // This should not be needed anymore. Use instead BOOST_THREAD_MAKE_RV_REF.
+#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
+ thread& operator=(thread x)
+ {
+ swap(x);
+ return *this;
+ }
+#endif
+#endif
+
+ thread& operator=(BOOST_THREAD_RV_REF(thread) other) BOOST_NOEXCEPT
+ {
+
+#if defined BOOST_THREAD_PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE
+ if (joinable()) std::terminate();
+#else
+ detach();
+#endif
+ thread_info=BOOST_THREAD_RV(other).thread_info;
+ BOOST_THREAD_RV(other).thread_info.reset();
+ return *this;
+ }
+
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ template <class F, class Arg, class ...Args>
+ thread(F&& f, Arg&& arg, Args&&... args) :
+ thread_info(make_thread_info(
+ thread_detail::decay_copy(boost::forward<F>(f)),
+ thread_detail::decay_copy(boost::forward<Arg>(arg)),
+ thread_detail::decay_copy(boost::forward<Args>(args))...)
+ )
+
+ {
+ start_thread();
+ }
+ template <class F, class Arg, class ...Args>
+ thread(attributes const& attrs, F&& f, Arg&& arg, Args&&... args) :
+ thread_info(make_thread_info(
+ thread_detail::decay_copy(boost::forward<F>(f)),
+ thread_detail::decay_copy(boost::forward<Arg>(arg)),
+ thread_detail::decay_copy(boost::forward<Args>(args))...)
+ )
+
+ {
+ start_thread(attrs);
+ }
+#else
+ template <class F,class A1>
+ thread(F f,A1 a1,typename disable_if<boost::thread_detail::is_convertible<F&,thread_attributes >, dummy* >::type=0):
+ thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1)))
+ {
+ start_thread();
+ }
+ template <class F,class A1,class A2>
+ thread(F f,A1 a1,A2 a2):
+ thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2)))
+ {
+ start_thread();
+ }
+
+ template <class F,class A1,class A2,class A3>
+ thread(F f,A1 a1,A2 a2,A3 a3):
+ thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3)))
+ {
+ start_thread();
+ }
+
+ template <class F,class A1,class A2,class A3,class A4>
+ thread(F f,A1 a1,A2 a2,A3 a3,A4 a4):
+ thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3,a4)))
+ {
+ start_thread();
+ }
+
+ template <class F,class A1,class A2,class A3,class A4,class A5>
+ thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5):
+ thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3,a4,a5)))
+ {
+ start_thread();
+ }
+
+ template <class F,class A1,class A2,class A3,class A4,class A5,class A6>
+ thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6):
+ thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3,a4,a5,a6)))
+ {
+ start_thread();
+ }
+
+ template <class F,class A1,class A2,class A3,class A4,class A5,class A6,class A7>
+ thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7):
+ thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3,a4,a5,a6,a7)))
+ {
+ start_thread();
+ }
+
+ template <class F,class A1,class A2,class A3,class A4,class A5,class A6,class A7,class A8>
+ thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8):
+ thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3,a4,a5,a6,a7,a8)))
+ {
+ start_thread();
+ }
+
+ template <class F,class A1,class A2,class A3,class A4,class A5,class A6,class A7,class A8,class A9>
+ thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9):
+ thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3,a4,a5,a6,a7,a8,a9)))
+ {
+ start_thread();
+ }
+#endif
+ void swap(thread& x) BOOST_NOEXCEPT
+ {
+ thread_info.swap(x.thread_info);
+ }
+
+ class id;
+#ifdef BOOST_THREAD_PLATFORM_PTHREAD
+ inline id get_id() const BOOST_NOEXCEPT;
+#else
+ id get_id() const BOOST_NOEXCEPT;
+#endif
+
+
+ bool joinable() const BOOST_NOEXCEPT;
+ private:
+ bool join_noexcept();
+ public:
+ inline void join();
+
+#ifdef BOOST_THREAD_USES_CHRONO
+#if defined(BOOST_THREAD_PLATFORM_WIN32)
+ template <class Rep, class Period>
+ bool try_join_for(const chrono::duration<Rep, Period>& rel_time)
+ {
+ chrono::milliseconds rel_time2= chrono::ceil<chrono::milliseconds>(rel_time);
+ return do_try_join_until(rel_time2.count());
+ }
+#else
+ template <class Rep, class Period>
+ bool try_join_for(const chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_join_until(chrono::steady_clock::now() + rel_time);
+ }
+#endif
+ template <class Clock, class Duration>
+ bool try_join_until(const chrono::time_point<Clock, Duration>& t)
+ {
+ using namespace chrono;
+ bool joined= false;
+ do {
+ system_clock::time_point s_now = system_clock::now();
+ typename Clock::duration d = ceil<nanoseconds>(t-Clock::now());
+ if (d <= Clock::duration::zero()) return false; // in case the Clock::time_point t is already reached
+ joined = try_join_until(s_now + d);
+ } while (! joined);
+ return true;
+ }
+ template <class Duration>
+ bool try_join_until(const chrono::time_point<chrono::system_clock, Duration>& t)
+ {
+ using namespace chrono;
+ typedef time_point<system_clock, nanoseconds> nano_sys_tmpt;
+ return try_join_until(nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch())));
+ }
+#endif
+#if defined(BOOST_THREAD_PLATFORM_WIN32)
+ private:
+ bool do_try_join_until_noexcept(uintmax_t milli, bool& res);
+ inline bool do_try_join_until(uintmax_t milli);
+ public:
+ bool timed_join(const system_time& abs_time);
+ //{
+ // return do_try_join_until(get_milliseconds_until(wait_until));
+ //}
+
+#ifdef BOOST_THREAD_USES_CHRONO
+ bool try_join_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp)
+ {
+ chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-chrono::system_clock::now());
+ return do_try_join_until(rel_time.count());
+ }
+#endif
+
+
+#else
+ private:
+ bool do_try_join_until_noexcept(struct timespec const &timeout, bool& res);
+ inline bool do_try_join_until(struct timespec const &timeout);
+ public:
+#if defined BOOST_THREAD_USES_DATETIME
+ bool timed_join(const system_time& abs_time)
+ {
+ struct timespec const ts=detail::to_timespec(abs_time);
+ return do_try_join_until(ts);
+ }
+#endif
+#ifdef BOOST_THREAD_USES_CHRONO
+ bool try_join_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp)
+ {
+ using namespace chrono;
+ nanoseconds d = tp.time_since_epoch();
+ timespec ts = boost::detail::to_timespec(d);
+ return do_try_join_until(ts);
+ }
+#endif
+
+#endif
+ public:
+
+#if defined BOOST_THREAD_USES_DATETIME
+ template<typename TimeDuration>
+ inline bool timed_join(TimeDuration const& rel_time)
+ {
+ return timed_join(get_system_time()+rel_time);
+ }
+#endif
+ void detach();
+
+ static unsigned hardware_concurrency() BOOST_NOEXCEPT;
+ static unsigned physical_concurrency() BOOST_NOEXCEPT;
+
+#define BOOST_THREAD_DEFINES_THREAD_NATIVE_HANDLE
+ typedef detail::thread_data_base::native_handle_type native_handle_type;
+ native_handle_type native_handle();
+
+#if defined BOOST_THREAD_PROVIDES_THREAD_EQ
+ // Use thread::id when comparisions are needed
+ // backwards compatibility
+ bool operator==(const thread& other) const;
+ bool operator!=(const thread& other) const;
+#endif
+#if defined BOOST_THREAD_USES_DATETIME
+ static inline void yield() BOOST_NOEXCEPT
+ {
+ this_thread::yield();
+ }
+
+ static inline void sleep(const system_time& xt)
+ {
+ this_thread::sleep(xt);
+ }
+#endif
+
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ // extensions
+ void interrupt();
+ bool interruption_requested() const BOOST_NOEXCEPT;
+#endif
+ };
+
+ inline void swap(thread& lhs,thread& rhs) BOOST_NOEXCEPT
+ {
+ return lhs.swap(rhs);
+ }
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ inline thread&& move(thread& t) BOOST_NOEXCEPT
+ {
+ return static_cast<thread&&>(t);
+ }
+#endif
+
+ BOOST_THREAD_DCL_MOVABLE(thread)
+
+ namespace this_thread
+ {
+#ifdef BOOST_THREAD_PLATFORM_PTHREAD
+ inline thread::id get_id() BOOST_NOEXCEPT;
+#else
+ thread::id BOOST_THREAD_DECL get_id() BOOST_NOEXCEPT;
+#endif
+
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ void BOOST_THREAD_DECL interruption_point();
+ bool BOOST_THREAD_DECL interruption_enabled() BOOST_NOEXCEPT;
+ bool BOOST_THREAD_DECL interruption_requested() BOOST_NOEXCEPT;
+#endif
+
+#if defined BOOST_THREAD_USES_DATETIME
+ inline BOOST_SYMBOL_VISIBLE void sleep(xtime const& abs_time)
+ {
+ sleep(system_time(abs_time));
+ }
+#endif
+ }
+
+ class BOOST_SYMBOL_VISIBLE thread::id
+ {
+ private:
+ friend inline
+ std::size_t
+ hash_value(const thread::id &v)
+ {
+#if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
+ return hash_value(v.thread_data);
+#else
+ return hash_value(v.thread_data.get());
+#endif
+ }
+
+#if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
+#if defined(BOOST_THREAD_PLATFORM_WIN32)
+ typedef unsigned int data;
+#else
+ typedef thread::native_handle_type data;
+#endif
+#else
+ typedef detail::thread_data_ptr data;
+#endif
+ data thread_data;
+
+ id(data thread_data_):
+ thread_data(thread_data_)
+ {}
+ friend class thread;
+ friend id BOOST_THREAD_DECL this_thread::get_id() BOOST_NOEXCEPT;
+ public:
+ id() BOOST_NOEXCEPT:
+#if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
+ thread_data(0)
+#else
+ thread_data()
+#endif
+ {}
+
+ id(const id& other) BOOST_NOEXCEPT :
+ thread_data(other.thread_data)
+ {}
+
+ bool operator==(const id& y) const BOOST_NOEXCEPT
+ {
+ return thread_data==y.thread_data;
+ }
+
+ bool operator!=(const id& y) const BOOST_NOEXCEPT
+ {
+ return thread_data!=y.thread_data;
+ }
+
+ bool operator<(const id& y) const BOOST_NOEXCEPT
+ {
+ return thread_data<y.thread_data;
+ }
+
+ bool operator>(const id& y) const BOOST_NOEXCEPT
+ {
+ return y.thread_data<thread_data;
+ }
+
+ bool operator<=(const id& y) const BOOST_NOEXCEPT
+ {
+ return !(y.thread_data<thread_data);
+ }
+
+ bool operator>=(const id& y) const BOOST_NOEXCEPT
+ {
+ return !(thread_data<y.thread_data);
+ }
+
+#ifndef BOOST_NO_IOSTREAM
+#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
+ template<class charT, class traits>
+ friend BOOST_SYMBOL_VISIBLE
+ std::basic_ostream<charT, traits>&
+ operator<<(std::basic_ostream<charT, traits>& os, const id& x)
+ {
+ if(x.thread_data)
+ {
+ io::ios_flags_saver ifs( os );
+ return os<< std::hex << x.thread_data;
+ }
+ else
+ {
+ return os<<"{Not-any-thread}";
+ }
+ }
+#else
+ template<class charT, class traits>
+ BOOST_SYMBOL_VISIBLE
+ std::basic_ostream<charT, traits>&
+ print(std::basic_ostream<charT, traits>& os) const
+ {
+ if(thread_data)
+ {
+ io::ios_flags_saver ifs( os );
+ return os<< std::hex << thread_data;
+ }
+ else
+ {
+ return os<<"{Not-any-thread}";
+ }
+ }
+
+#endif
+#endif
+ };
+
+#ifdef BOOST_THREAD_PLATFORM_PTHREAD
+ thread::id thread::get_id() const BOOST_NOEXCEPT
+ {
+ #if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
+ return const_cast<thread*>(this)->native_handle();
+ #else
+ detail::thread_data_ptr const local_thread_info=(get_thread_info)();
+ return (local_thread_info? id(local_thread_info) : id());
+ #endif
+ }
+
+ namespace this_thread
+ {
+ inline thread::id get_id() BOOST_NOEXCEPT
+ {
+ #if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
+ return pthread_self();
+ #else
+ boost::detail::thread_data_base* const thread_info=get_or_make_current_thread_data();
+ return (thread_info?thread::id(thread_info->shared_from_this()):thread::id());
+ #endif
+ }
+ }
+#endif
+ void thread::join() {
+ if (this_thread::get_id() == get_id())
+ boost::throw_exception(thread_resource_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost thread: trying joining itself"));
+
+ BOOST_THREAD_VERIFY_PRECONDITION( join_noexcept(),
+ thread_resource_error(static_cast<int>(system::errc::invalid_argument), "boost thread: thread not joinable")
+ );
+ }
+
+#ifdef BOOST_THREAD_PLATFORM_PTHREAD
+ bool thread::do_try_join_until(struct timespec const &timeout)
+#else
+ bool thread::do_try_join_until(uintmax_t timeout)
+#endif
+ {
+ if (this_thread::get_id() == get_id())
+ boost::throw_exception(thread_resource_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost thread: trying joining itself"));
+ bool res;
+ if (do_try_join_until_noexcept(timeout, res))
+ {
+ return res;
+ }
+ else
+ {
+ BOOST_THREAD_THROW_ELSE_RETURN(
+ (thread_resource_error(static_cast<int>(system::errc::invalid_argument), "boost thread: thread not joinable")),
+ false
+ );
+ }
+ }
+
+#if !defined(BOOST_NO_IOSTREAM) && defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
+ template<class charT, class traits>
+ BOOST_SYMBOL_VISIBLE
+ std::basic_ostream<charT, traits>&
+ operator<<(std::basic_ostream<charT, traits>& os, const thread::id& x)
+ {
+ return x.print(os);
+ }
+#endif
+
+#if defined BOOST_THREAD_PROVIDES_THREAD_EQ
+ inline bool thread::operator==(const thread& other) const
+ {
+ return get_id()==other.get_id();
+ }
+
+ inline bool thread::operator!=(const thread& other) const
+ {
+ return get_id()!=other.get_id();
+ }
+#endif
+
+ namespace detail
+ {
+ struct thread_exit_function_base
+ {
+ virtual ~thread_exit_function_base()
+ {}
+ virtual void operator()()=0;
+ };
+
+ template<typename F>
+ struct thread_exit_function:
+ thread_exit_function_base
+ {
+ F f;
+
+ thread_exit_function(F f_):
+ f(f_)
+ {}
+
+ void operator()()
+ {
+ f();
+ }
+ };
+
+ void BOOST_THREAD_DECL add_thread_exit_function(thread_exit_function_base*);
+ struct shared_state_base;
+#if defined(BOOST_THREAD_PLATFORM_WIN32)
+ inline void make_ready_at_thread_exit(shared_ptr<shared_state_base> as)
+ {
+ detail::thread_data_base* const current_thread_data(detail::get_current_thread_data());
+ if(current_thread_data)
+ {
+ current_thread_data->make_ready_at_thread_exit(as);
+ }
+ }
+#else
+ void BOOST_THREAD_DECL make_ready_at_thread_exit(shared_ptr<shared_state_base> as);
+#endif
+ }
+
+ namespace this_thread
+ {
+ template<typename F>
+ void at_thread_exit(F f)
+ {
+ detail::thread_exit_function_base* const thread_exit_func=detail::heap_new<detail::thread_exit_function<F> >(f);
+ detail::add_thread_exit_function(thread_exit_func);
+ }
+ }
+}
+
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/detail/thread_group.hpp b/src/third_party/boost-1.60.0/boost/thread/detail/thread_group.hpp
new file mode 100644
index 00000000000..4105c734688
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/detail/thread_group.hpp
@@ -0,0 +1,155 @@
+#ifndef BOOST_THREAD_DETAIL_THREAD_GROUP_HPP
+#define BOOST_THREAD_DETAIL_THREAD_GROUP_HPP
+// Distributed under the 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 2007-9 Anthony Williams
+
+#include <list>
+#include <boost/thread/csbl/memory/unique_ptr.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/lock_guard.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4251)
+#endif
+
+namespace boost
+{
+ class thread_group
+ {
+ private:
+ thread_group(thread_group const&);
+ thread_group& operator=(thread_group const&);
+ public:
+ thread_group() {}
+ ~thread_group()
+ {
+ for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
+ it!=end;
+ ++it)
+ {
+ delete *it;
+ }
+ }
+
+ bool is_this_thread_in()
+ {
+ thread::id id = this_thread::get_id();
+ boost::shared_lock<shared_mutex> guard(m);
+ for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
+ it!=end;
+ ++it)
+ {
+ if ((*it)->get_id() == id)
+ return true;
+ }
+ return false;
+ }
+
+ bool is_thread_in(thread* thrd)
+ {
+ if(thrd)
+ {
+ thread::id id = thrd->get_id();
+ boost::shared_lock<shared_mutex> guard(m);
+ for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
+ it!=end;
+ ++it)
+ {
+ if ((*it)->get_id() == id)
+ return true;
+ }
+ return false;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ template<typename F>
+ thread* create_thread(F threadfunc)
+ {
+ boost::lock_guard<shared_mutex> guard(m);
+ boost::csbl::unique_ptr<thread> new_thread(new thread(threadfunc));
+ threads.push_back(new_thread.get());
+ return new_thread.release();
+ }
+
+ void add_thread(thread* thrd)
+ {
+ if(thrd)
+ {
+ BOOST_THREAD_ASSERT_PRECONDITION( ! is_thread_in(thrd) ,
+ thread_resource_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost::thread_group: trying to add a duplicated thread")
+ );
+
+ boost::lock_guard<shared_mutex> guard(m);
+ threads.push_back(thrd);
+ }
+ }
+
+ void remove_thread(thread* thrd)
+ {
+ boost::lock_guard<shared_mutex> guard(m);
+ std::list<thread*>::iterator const it=std::find(threads.begin(),threads.end(),thrd);
+ if(it!=threads.end())
+ {
+ threads.erase(it);
+ }
+ }
+
+ void join_all()
+ {
+ BOOST_THREAD_ASSERT_PRECONDITION( ! is_this_thread_in() ,
+ thread_resource_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost::thread_group: trying joining itself")
+ );
+ boost::shared_lock<shared_mutex> guard(m);
+
+ for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
+ it!=end;
+ ++it)
+ {
+ if ((*it)->joinable())
+ (*it)->join();
+ }
+ }
+
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ void interrupt_all()
+ {
+ boost::shared_lock<shared_mutex> guard(m);
+
+ for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
+ it!=end;
+ ++it)
+ {
+ (*it)->interrupt();
+ }
+ }
+#endif
+
+ size_t size() const
+ {
+ boost::shared_lock<shared_mutex> guard(m);
+ return threads.size();
+ }
+
+ private:
+ std::list<thread*> threads;
+ mutable shared_mutex m;
+ };
+}
+
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/detail/thread_heap_alloc.hpp b/src/third_party/boost-1.60.0/boost/thread/detail/thread_heap_alloc.hpp
new file mode 100644
index 00000000000..2f9bfd5c0b6
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/detail/thread_heap_alloc.hpp
@@ -0,0 +1,23 @@
+#ifndef BOOST_THREAD_THREAD_HEAP_ALLOC_HPP
+#define BOOST_THREAD_THREAD_HEAP_ALLOC_HPP
+
+// thread_heap_alloc.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/thread/detail/platform.hpp>
+
+#if defined(BOOST_THREAD_PLATFORM_WIN32)
+#include <boost/thread/win32/thread_heap_alloc.hpp>
+#elif defined(BOOST_THREAD_PLATFORM_PTHREAD)
+#include <boost/thread/pthread/thread_heap_alloc.hpp>
+#else
+#error "Boost threads unavailable on this platform"
+#endif
+
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/detail/thread_interruption.hpp b/src/third_party/boost-1.60.0/boost/thread/detail/thread_interruption.hpp
new file mode 100644
index 00000000000..5d7d10fecdf
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/detail/thread_interruption.hpp
@@ -0,0 +1,39 @@
+#ifndef BOOST_THREAD_DETAIL_THREAD_INTERRUPTION_HPP
+#define BOOST_THREAD_DETAIL_THREAD_INTERRUPTION_HPP
+// Distributed under the 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 2007-9 Anthony Williams
+// (C) Copyright 2012 Vicente J. Botet Escriba
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/detail/delete.hpp>
+
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+
+namespace boost
+{
+ namespace this_thread
+ {
+ class BOOST_THREAD_DECL disable_interruption
+ {
+ bool interruption_was_enabled;
+ friend class restore_interruption;
+ public:
+ BOOST_THREAD_NO_COPYABLE(disable_interruption)
+ disable_interruption() BOOST_NOEXCEPT;
+ ~disable_interruption() BOOST_NOEXCEPT;
+ };
+
+ class BOOST_THREAD_DECL restore_interruption
+ {
+ public:
+ BOOST_THREAD_NO_COPYABLE(restore_interruption)
+ explicit restore_interruption(disable_interruption& d) BOOST_NOEXCEPT;
+ ~restore_interruption() BOOST_NOEXCEPT;
+ };
+ }
+}
+
+#endif // BOOST_THREAD_PROVIDES_INTERRUPTIONS
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/detail/tss_hooks.hpp b/src/third_party/boost-1.60.0/boost/thread/detail/tss_hooks.hpp
new file mode 100644
index 00000000000..b2ceece3ddd
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/detail/tss_hooks.hpp
@@ -0,0 +1,65 @@
+// (C) Copyright Michael Glassford 2004.
+// Use, modification and distribution are subject to the
+// 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(BOOST_TLS_HOOKS_HPP)
+#define BOOST_TLS_HOOKS_HPP
+
+#include <boost/thread/detail/config.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+#if defined(BOOST_HAS_WINTHREADS)
+
+namespace boost
+{
+ BOOST_THREAD_DECL void __cdecl on_process_enter(void);
+ //Function to be called when the exe or dll
+ //that uses Boost.Threads first starts
+ //or is first loaded.
+ //Should be called only before the first call to
+ //on_thread_enter().
+ //Called automatically by Boost.Threads when
+ //a method for doing so has been discovered.
+ //May be omitted; may be called multiple times.
+
+ BOOST_THREAD_DECL void __cdecl on_process_exit(void);
+ //Function to be called when the exe or dll
+ //that uses Boost.Threads first starts
+ //or is first loaded.
+ //Should be called only after the last call to
+ //on_exit_thread().
+ //Called automatically by Boost.Threads when
+ //a method for doing so has been discovered.
+ //Must not be omitted; may be called multiple times.
+
+ BOOST_THREAD_DECL void __cdecl on_thread_enter(void);
+ //Function to be called just after a thread starts
+ //in an exe or dll that uses Boost.Threads.
+ //Must be called in the context of the thread
+ //that is starting.
+ //Called automatically by Boost.Threads when
+ //a method for doing so has been discovered.
+ //May be omitted; may be called multiple times.
+
+ BOOST_THREAD_DECL void __cdecl on_thread_exit(void);
+ //Function to be called just be fore a thread ends
+ //in an exe or dll that uses Boost.Threads.
+ //Must be called in the context of the thread
+ //that is ending.
+ //Called automatically by Boost.Threads when
+ //a method for doing so has been discovered.
+ //Must not be omitted; may be called multiple times.
+
+ void tss_cleanup_implemented();
+ //Dummy function used both to detect whether tss cleanup
+ //cleanup has been implemented and to force
+ //it to be linked into the Boost.Threads library.
+}
+
+#endif //defined(BOOST_HAS_WINTHREADS)
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif //!defined(BOOST_TLS_HOOKS_HPP)
diff --git a/src/third_party/boost-1.60.0/boost/thread/detail/variadic_footer.hpp b/src/third_party/boost-1.60.0/boost/thread/detail/variadic_footer.hpp
new file mode 100644
index 00000000000..9ae25a847c3
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/detail/variadic_footer.hpp
@@ -0,0 +1,10 @@
+// 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)
+
+
+#if defined BOOST_NO_CXX11_VARIADIC_TEMPLATES
+
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/detail/variadic_header.hpp b/src/third_party/boost-1.60.0/boost/thread/detail/variadic_header.hpp
new file mode 100644
index 00000000000..8015ae33cc2
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/detail/variadic_header.hpp
@@ -0,0 +1,19 @@
+// 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)
+
+#include <boost/config.hpp>
+
+//#if defined BOOST_NO_CXX11_VARIADIC_TEMPLATES
+
+#include <boost/preprocessor/facilities/intercept.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+
+#ifndef BOOST_THREAD_MAX_ARGS
+#define BOOST_THREAD_MAX_ARGS 9
+#endif
+
+//#endif
+
diff --git a/src/third_party/boost-1.60.0/boost/thread/exceptional_ptr.hpp b/src/third_party/boost-1.60.0/boost/thread/exceptional_ptr.hpp
new file mode 100644
index 00000000000..49547923d92
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/exceptional_ptr.hpp
@@ -0,0 +1,44 @@
+// Distributed under the 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 2014 Vicente J. Botet Escriba
+
+#ifndef BOOST_THREAD_EXCEPTIONAL_PTR_HPP
+#define BOOST_THREAD_EXCEPTIONAL_PTR_HPP
+
+#include <boost/thread/detail/move.hpp>
+#include <boost/exception_ptr.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ struct exceptional_ptr {
+ exception_ptr ptr_;
+
+ exceptional_ptr() : ptr_() {}
+ explicit exceptional_ptr(exception_ptr ex) : ptr_(ex) {}
+ template <class E>
+ explicit exceptional_ptr(BOOST_FWD_REF(E) ex) : ptr_(boost::copy_exception(boost::forward<E>(ex))) {}
+ };
+
+ template <class E>
+ inline exceptional_ptr make_exceptional(BOOST_FWD_REF(E) ex) {
+ return exceptional_ptr(boost::forward<E>(ex));
+ }
+
+ inline exceptional_ptr make_exceptional(exception_ptr ex)
+ {
+ return exceptional_ptr(ex);
+ }
+
+ inline exceptional_ptr make_exceptional()
+ {
+ return exceptional_ptr();
+ }
+
+} // namespace boost
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/exceptions.hpp b/src/third_party/boost-1.60.0/boost/thread/exceptions.hpp
new file mode 100644
index 00000000000..d97465b754e
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/exceptions.hpp
@@ -0,0 +1,225 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+// Copyright (C) 2007-9 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)
+
+#ifndef BOOST_THREAD_EXCEPTIONS_PDM070801_H
+#define BOOST_THREAD_EXCEPTIONS_PDM070801_H
+
+#include <boost/thread/detail/config.hpp>
+
+// pdm: Sorry, but this class is used all over the place & I end up
+// with recursive headers if I don't separate it
+// wek: Not sure why recursive headers would cause compilation problems
+// given the include guards, but regardless it makes sense to
+// seperate this out any way.
+
+#include <string>
+#include <stdexcept>
+#include <boost/system/system_error.hpp>
+#include <boost/system/error_code.hpp>
+
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ class BOOST_SYMBOL_VISIBLE thread_interrupted
+ {};
+#endif
+
+ class BOOST_SYMBOL_VISIBLE thread_exception:
+ public system::system_error
+ //public std::exception
+ {
+ typedef system::system_error base_type;
+ public:
+ thread_exception()
+ : base_type(0,system::system_category())
+ {}
+
+ thread_exception(int sys_error_code)
+ : base_type(sys_error_code, system::system_category())
+ {}
+
+ thread_exception( int ev, const char * what_arg )
+ : base_type(system::error_code(ev, system::system_category()), what_arg)
+ {
+ }
+ thread_exception( int ev, const std::string & what_arg )
+ : base_type(system::error_code(ev, system::system_category()), what_arg)
+ {
+ }
+
+ ~thread_exception() throw()
+ {}
+
+
+ int native_error() const
+ {
+ return code().value();
+ }
+
+ };
+
+ class BOOST_SYMBOL_VISIBLE condition_error:
+ public system::system_error
+ //public std::exception
+ {
+ typedef system::system_error base_type;
+ public:
+ condition_error()
+ : base_type(system::error_code(0, system::system_category()), "Condition error")
+ {}
+ condition_error( int ev )
+ : base_type(system::error_code(ev, system::system_category()), "Condition error")
+ {
+ }
+ condition_error( int ev, const char * what_arg )
+ : base_type(system::error_code(ev, system::system_category()), what_arg)
+ {
+ }
+ condition_error( int ev, const std::string & what_arg )
+ : base_type(system::error_code(ev, system::system_category()), what_arg)
+ {
+ }
+ };
+
+
+ class BOOST_SYMBOL_VISIBLE lock_error:
+ public thread_exception
+ {
+ typedef thread_exception base_type;
+ public:
+ lock_error()
+ : base_type(0, "boost::lock_error")
+ {}
+
+ lock_error( int ev )
+ : base_type(ev, "boost::lock_error")
+ {
+ }
+ lock_error( int ev, const char * what_arg )
+ : base_type(ev, what_arg)
+ {
+ }
+ lock_error( int ev, const std::string & what_arg )
+ : base_type(ev, what_arg)
+ {
+ }
+
+ ~lock_error() throw()
+ {}
+
+ };
+
+ class BOOST_SYMBOL_VISIBLE thread_resource_error:
+ public thread_exception
+ {
+ typedef thread_exception base_type;
+ public:
+ thread_resource_error()
+ : base_type(static_cast<int>(system::errc::resource_unavailable_try_again), "boost::thread_resource_error")
+ {}
+
+ thread_resource_error( int ev )
+ : base_type(ev, "boost::thread_resource_error")
+ {
+ }
+ thread_resource_error( int ev, const char * what_arg )
+ : base_type(ev, what_arg)
+ {
+ }
+ thread_resource_error( int ev, const std::string & what_arg )
+ : base_type(ev, what_arg)
+ {
+ }
+
+
+ ~thread_resource_error() throw()
+ {}
+
+ };
+
+ class BOOST_SYMBOL_VISIBLE unsupported_thread_option:
+ public thread_exception
+ {
+ typedef thread_exception base_type;
+ public:
+ unsupported_thread_option()
+ : base_type(static_cast<int>(system::errc::invalid_argument), "boost::unsupported_thread_option")
+ {}
+
+ unsupported_thread_option( int ev )
+ : base_type(ev, "boost::unsupported_thread_option")
+ {
+ }
+ unsupported_thread_option( int ev, const char * what_arg )
+ : base_type(ev, what_arg)
+ {
+ }
+ unsupported_thread_option( int ev, const std::string & what_arg )
+ : base_type(ev, what_arg)
+ {
+ }
+
+ };
+
+ class BOOST_SYMBOL_VISIBLE invalid_thread_argument:
+ public thread_exception
+ {
+ typedef thread_exception base_type;
+ public:
+ invalid_thread_argument()
+ : base_type(static_cast<int>(system::errc::invalid_argument), "boost::invalid_thread_argument")
+ {}
+
+ invalid_thread_argument( int ev )
+ : base_type(ev, "boost::invalid_thread_argument")
+ {
+ }
+ invalid_thread_argument( int ev, const char * what_arg )
+ : base_type(ev, what_arg)
+ {
+ }
+ invalid_thread_argument( int ev, const std::string & what_arg )
+ : base_type(ev, what_arg)
+ {
+ }
+
+ };
+
+ class BOOST_SYMBOL_VISIBLE thread_permission_error:
+ public thread_exception
+ {
+ typedef thread_exception base_type;
+ public:
+ thread_permission_error()
+ : base_type(static_cast<int>(system::errc::permission_denied), "boost::thread_permission_error")
+ {}
+
+ thread_permission_error( int ev )
+ : base_type(ev, "boost::thread_permission_error")
+ {
+ }
+ thread_permission_error( int ev, const char * what_arg )
+ : base_type(ev, what_arg)
+ {
+ }
+ thread_permission_error( int ev, const std::string & what_arg )
+ : base_type(ev, what_arg)
+ {
+ }
+
+ };
+
+} // namespace boost
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/executor.hpp b/src/third_party/boost-1.60.0/boost/thread/executor.hpp
new file mode 100644
index 00000000000..c2b85a0eabe
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/executor.hpp
@@ -0,0 +1,15 @@
+// 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)
+//
+// 2013/09 Vicente J. Botet Escriba
+// Adapt to boost from CCIA C++11 implementation
+
+#ifndef BOOST_THREAD_EXECUTOR_HPP
+#define BOOST_THREAD_EXECUTOR_HPP
+
+#include <boost/thread/executors/executor.hpp>
+#include <boost/thread/executors/executor_adaptor.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/executors/basic_thread_pool.hpp b/src/third_party/boost-1.60.0/boost/thread/executors/basic_thread_pool.hpp
new file mode 100644
index 00000000000..e0d4df2c76b
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/executors/basic_thread_pool.hpp
@@ -0,0 +1,318 @@
+// Copyright (C) 2013-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)
+//
+// 2013/09 Vicente J. Botet Escriba
+// Adapt to boost from CCIA C++11 implementation
+// first implementation of a simple pool thread using a vector of threads and a sync_queue.
+
+#ifndef BOOST_THREAD_EXECUTORS_BASIC_THREAD_POOL_HPP
+#define BOOST_THREAD_EXECUTORS_BASIC_THREAD_POOL_HPP
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/detail/delete.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/concurrent_queues/sync_queue.hpp>
+#include <boost/thread/executors/work.hpp>
+#include <boost/thread/csbl/vector.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+namespace executors
+{
+ class basic_thread_pool
+ {
+ public:
+ /// type-erasure to store the works to do
+ typedef executors::work work;
+ private:
+ typedef thread thread_t;
+ /// A move aware vector type
+ typedef csbl::vector<thread_t> thread_vector;
+
+ /// A move aware vector
+ thread_vector threads;
+ /// the thread safe work queue
+ concurrent::sync_queue<work > work_queue;
+
+ public:
+ /**
+ * Effects: try to execute one task.
+ * Returns: whether a task has been executed.
+ * Throws: whatever the current task constructor throws or the task() throws.
+ */
+ bool try_executing_one()
+ {
+ try
+ {
+ work task;
+ if (work_queue.try_pull(task) == queue_op_status::success)
+ {
+ task();
+ return true;
+ }
+ return false;
+ }
+ catch (...)
+ {
+ std::terminate();
+ //return false;
+ }
+ }
+ /**
+ * Effects: schedule one task or yields
+ * Throws: whatever the current task constructor throws or the task() throws.
+ */
+ void schedule_one_or_yield()
+ {
+ if ( ! try_executing_one())
+ {
+ this_thread::yield();
+ }
+ }
+ private:
+
+ /**
+ * The main loop of the worker threads
+ */
+ void worker_thread()
+ {
+ try
+ {
+ for(;;)
+ {
+ work task;
+ queue_op_status st = work_queue.wait_pull(task);
+ if (st == queue_op_status::closed) {
+ return;
+ }
+ task();
+ }
+ }
+ catch (...)
+ {
+ std::terminate();
+ return;
+ }
+ }
+#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ template <class AtThreadEntry>
+ void worker_thread1(AtThreadEntry& at_thread_entry)
+ {
+ at_thread_entry(*this);
+ worker_thread();
+ }
+#endif
+ void worker_thread2(void(*at_thread_entry)(basic_thread_pool&))
+ {
+ at_thread_entry(*this);
+ worker_thread();
+ }
+ template <class AtThreadEntry>
+ void worker_thread3(BOOST_THREAD_FWD_REF(AtThreadEntry) at_thread_entry)
+ {
+ at_thread_entry(*this);
+ worker_thread();
+ }
+ static void do_nothing_at_thread_entry(basic_thread_pool&) {}
+
+ public:
+ /// basic_thread_pool is not copyable.
+ BOOST_THREAD_NO_COPYABLE(basic_thread_pool)
+
+ /**
+ * \b Effects: creates a thread pool that runs closures on \c thread_count threads.
+ *
+ * \b Throws: Whatever exception is thrown while initializing the needed resources.
+ */
+ basic_thread_pool(unsigned const thread_count = thread::hardware_concurrency()+1)
+ {
+ try
+ {
+ threads.reserve(thread_count);
+ for (unsigned i = 0; i < thread_count; ++i)
+ {
+#if 1
+ thread th (&basic_thread_pool::worker_thread, this);
+ threads.push_back(thread_t(boost::move(th)));
+#else
+ threads.push_back(thread_t(&basic_thread_pool::worker_thread, this)); // do not compile
+#endif
+ }
+ }
+ catch (...)
+ {
+ close();
+ throw;
+ }
+ }
+ /**
+ * \b Effects: creates a thread pool that runs closures on \c thread_count threads
+ * and executes the at_thread_entry function at the entry of each created thread. .
+ *
+ * \b Throws: Whatever exception is thrown while initializing the needed resources.
+ */
+#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ template <class AtThreadEntry>
+ basic_thread_pool( unsigned const thread_count, AtThreadEntry& at_thread_entry)
+ {
+ try
+ {
+ threads.reserve(thread_count);
+ for (unsigned i = 0; i < thread_count; ++i)
+ {
+ thread th (&basic_thread_pool::worker_thread1<AtThreadEntry>, this, at_thread_entry);
+ threads.push_back(thread_t(boost::move(th)));
+ //threads.push_back(thread_t(&basic_thread_pool::worker_thread, this)); // do not compile
+ }
+ }
+ catch (...)
+ {
+ close();
+ throw;
+ }
+ }
+#endif
+ basic_thread_pool( unsigned const thread_count, void(*at_thread_entry)(basic_thread_pool&))
+ {
+ try
+ {
+ threads.reserve(thread_count);
+ for (unsigned i = 0; i < thread_count; ++i)
+ {
+ thread th (&basic_thread_pool::worker_thread2, this, at_thread_entry);
+ threads.push_back(thread_t(boost::move(th)));
+ //threads.push_back(thread_t(&basic_thread_pool::worker_thread, this)); // do not compile
+ }
+ }
+ catch (...)
+ {
+ close();
+ throw;
+ }
+ }
+ template <class AtThreadEntry>
+ basic_thread_pool( unsigned const thread_count, BOOST_THREAD_FWD_REF(AtThreadEntry) at_thread_entry)
+ {
+ try
+ {
+ threads.reserve(thread_count);
+ for (unsigned i = 0; i < thread_count; ++i)
+ {
+ thread th (&basic_thread_pool::worker_thread3<AtThreadEntry>, this, boost::forward<AtThreadEntry>(at_thread_entry));
+ threads.push_back(thread_t(boost::move(th)));
+ //threads.push_back(thread_t(&basic_thread_pool::worker_thread, this)); // do not compile
+ }
+ }
+ catch (...)
+ {
+ close();
+ throw;
+ }
+ }
+ /**
+ * \b Effects: Destroys the thread pool.
+ *
+ * \b Synchronization: The completion of all the closures happen before the completion of the \c basic_thread_pool destructor.
+ */
+ ~basic_thread_pool()
+ {
+ // signal to all the worker threads that there will be no more submissions.
+ close();
+ // joins all the threads before destroying the thread pool resources (e.g. the queue).
+ join();
+ }
+
+ /**
+ * \b Effects: join all the threads.
+ */
+ void join()
+ {
+ for (unsigned i = 0; i < threads.size(); ++i)
+ {
+ threads[i].join();
+ }
+ }
+
+ /**
+ * \b Effects: close the \c basic_thread_pool for submissions.
+ * The worker threads will work until there is no more closures to run.
+ */
+ void close()
+ {
+ work_queue.close();
+ }
+
+ /**
+ * \b Returns: whether the pool is closed for submissions.
+ */
+ bool closed()
+ {
+ return work_queue.closed();
+ }
+
+ /**
+ * \b Requires: \c Closure is a model of \c Callable(void()) and a model of \c CopyConstructible/MoveConstructible.
+ *
+ * \b Effects: The specified \c closure will be scheduled for execution at some point in the future.
+ * If invoked closure throws an exception the \c basic_thread_pool will call \c std::terminate, as is the case with threads.
+ *
+ * \b Synchronization: completion of \c closure on a particular thread happens before destruction of thread's thread local variables.
+ *
+ * \b Throws: \c sync_queue_is_closed if the thread pool is closed.
+ * Whatever exception that can be throw while storing the closure.
+ */
+ void submit(BOOST_THREAD_RV_REF(work) closure) {
+ work_queue.push(boost::move(closure));
+ }
+
+#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ template <typename Closure>
+ void submit(Closure & closure)
+ {
+ submit(work(closure));
+ }
+#endif
+ void submit(void (*closure)())
+ {
+ submit(work(closure));
+ }
+
+ template <typename Closure>
+ void submit(BOOST_THREAD_FWD_REF(Closure) closure)
+ {
+ //submit(work(boost::forward<Closure>(closure)));
+ work w((boost::forward<Closure>(closure)));
+ submit(boost::move(w));
+ }
+
+ /**
+ * \b Requires: This must be called from an scheduled task.
+ *
+ * \b Effects: reschedule functions until pred()
+ */
+ template <typename Pred>
+ bool reschedule_until(Pred const& pred)
+ {
+ do {
+ if ( ! try_executing_one())
+ {
+ return false;
+ }
+ } while (! pred());
+ return true;
+ }
+
+ };
+}
+using executors::basic_thread_pool;
+
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/executors/detail/priority_executor_base.hpp b/src/third_party/boost-1.60.0/boost/thread/executors/detail/priority_executor_base.hpp
new file mode 100644
index 00000000000..2191c0b37a3
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/executors/detail/priority_executor_base.hpp
@@ -0,0 +1,77 @@
+// 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)
+//
+
+#ifndef BOOST_THREAD_EXECUTORS_DETAIL_PRIORITY_EXECUTOR_BASE_HPP
+#define BOOST_THREAD_EXECUTORS_DETAIL_PRIORITY_EXECUTOR_BASE_HPP
+
+#include <boost/atomic.hpp>
+#include <boost/function.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/concurrent_queues/sync_timed_queue.hpp>
+#include <boost/thread/executors/work.hpp>
+
+namespace boost
+{
+namespace executors
+{
+namespace detail
+{
+ template <class Queue>
+ class priority_executor_base
+ {
+ public:
+ //typedef boost::function<void()> work;
+ typedef executors::work_pq work;
+ protected:
+ typedef Queue queue_type;
+ queue_type _workq;
+
+ priority_executor_base() {}
+ public:
+
+ ~priority_executor_base()
+ {
+ if(!closed())
+ {
+ this->close();
+ }
+ }
+
+ void close()
+ {
+ _workq.close();
+ }
+
+ bool closed()
+ {
+ return _workq.closed();
+ }
+
+ void loop()
+ {
+ try
+ {
+ for(;;)
+ {
+ work task;
+ queue_op_status st = _workq.wait_pull(task);
+ if (st == queue_op_status::closed) return;
+ task();
+ }
+ }
+ catch (...)
+ {
+ std::terminate();
+ return;
+ }
+ }
+ }; //end class
+
+} //end detail namespace
+} //end executors namespace
+} //end boost namespace
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/executors/detail/scheduled_executor_base.hpp b/src/third_party/boost-1.60.0/boost/thread/executors/detail/scheduled_executor_base.hpp
new file mode 100644
index 00000000000..ec0038f7e3e
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/executors/detail/scheduled_executor_base.hpp
@@ -0,0 +1,66 @@
+// 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)
+//
+
+#ifndef BOOST_THREAD_EXECUTORS_DETAIL_SCHEDULED_EXECUTOR_BASE_HPP
+#define BOOST_THREAD_EXECUTORS_DETAIL_SCHEDULED_EXECUTOR_BASE_HPP
+
+#include <boost/thread/concurrent_queues/sync_timed_queue.hpp>
+#include <boost/thread/executors/detail/priority_executor_base.hpp>
+#include <boost/thread/executors/work.hpp>
+#include <boost/thread/thread.hpp>
+
+#include <boost/atomic.hpp>
+#include <boost/function.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+namespace executors
+{
+namespace detail
+{
+ template <class Clock=chrono::steady_clock>
+ class scheduled_executor_base : public priority_executor_base<concurrent::sync_timed_queue<executors::work_pq, Clock > >
+ {
+ public:
+ typedef executors::work_pq work;
+ typedef Clock clock;
+ typedef typename clock::duration duration;
+ typedef typename clock::time_point time_point;
+ protected:
+
+ scheduled_executor_base() {}
+ public:
+
+ ~scheduled_executor_base()
+ {
+ if(! this->closed())
+ {
+ this->close();
+ }
+ }
+
+ void submit_at(work w, const time_point& tp)
+ {
+ this->_workq.push(boost::move(w), tp);
+ }
+
+ void submit_after(work w, const duration& dura)
+ {
+ this->_workq.push(boost::move(w), dura+clock::now());
+ }
+
+ }; //end class
+
+} //end detail namespace
+} //end executors namespace
+} //end boost namespace
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/executors/executor.hpp b/src/third_party/boost-1.60.0/boost/thread/executors/executor.hpp
new file mode 100644
index 00000000000..96198201f08
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/executors/executor.hpp
@@ -0,0 +1,148 @@
+// Copyright (C) 2013,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)
+//
+// 2013/09 Vicente J. Botet Escriba
+// Adapt to boost from CCIA C++11 implementation
+
+#ifndef BOOST_THREAD_EXECUTORS_EXECUTOR_HPP
+#define BOOST_THREAD_EXECUTORS_EXECUTOR_HPP
+
+#include <boost/thread/detail/config.hpp>
+
+#include <boost/thread/detail/delete.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/executors/work.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ namespace executors
+ {
+ class executor
+ {
+ public:
+ /// type-erasure to store the works to do
+ typedef executors::work work;
+
+ /// executor is not copyable.
+ BOOST_THREAD_NO_COPYABLE(executor)
+ executor() {}
+
+ /**
+ * \par Effects
+ * Destroys the executor.
+ *
+ * \par Synchronization
+ * The completion of all the closures happen before the completion of the executor destructor.
+ */
+ virtual ~executor() {};
+
+ /**
+ * \par Effects
+ * Close the \c executor for submissions.
+ * The worker threads will work until there is no more closures to run.
+ */
+ virtual void close() = 0;
+
+ /**
+ * \par Returns
+ * Whether the pool is closed for submissions.
+ */
+ virtual bool closed() = 0;
+
+ /**
+ * \par Effects
+ * The specified closure will be scheduled for execution at some point in the future.
+ * If invoked closure throws an exception the executor will call std::terminate, as is the case with threads.
+ *
+ * \par Synchronization
+ * Ccompletion of closure on a particular thread happens before destruction of thread's thread local variables.
+ *
+ * \par Throws
+ * \c sync_queue_is_closed if the thread pool is closed.
+ * Whatever exception that can be throw while storing the closure.
+ */
+ virtual void submit(BOOST_THREAD_RV_REF(work) closure) = 0;
+// virtual void submit(work& closure) = 0;
+
+ /**
+ * \par Requires
+ * \c Closure is a model of Callable(void()) and a model of CopyConstructible/MoveConstructible.
+ *
+ * \par Effects
+ * The specified closure will be scheduled for execution at some point in the future.
+ * If invoked closure throws an exception the thread pool will call std::terminate, as is the case with threads.
+ *
+ * \par Synchronization
+ * Completion of closure on a particular thread happens before destruction of thread's thread local variables.
+ *
+ * \par Throws
+ * \c sync_queue_is_closed if the thread pool is closed.
+ * Whatever exception that can be throw while storing the closure.
+ */
+
+#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ template <typename Closure>
+ void submit(Closure & closure)
+ {
+ work w ((closure));
+ submit(boost::move(w));
+ }
+#endif
+ void submit(void (*closure)())
+ {
+ work w ((closure));
+ submit(boost::move(w));
+ }
+
+ template <typename Closure>
+ void submit(BOOST_THREAD_FWD_REF(Closure) closure)
+ {
+ //submit(work(boost::forward<Closure>(closure)));
+ work w((boost::forward<Closure>(closure)));
+ submit(boost::move(w));
+ }
+
+ /**
+ * \par Effects
+ * Try to execute one task.
+ *
+ * \par Returns
+ * Whether a task has been executed.
+ *
+ * \par Throws
+ * Whatever the current task constructor throws or the task() throws.
+ */
+ virtual bool try_executing_one() = 0;
+
+ /**
+ * \par Requires
+ * This must be called from an scheduled task.
+ *
+ * \par Effects
+ * Reschedule functions until pred()
+ */
+ template <typename Pred>
+ bool reschedule_until(Pred const& pred)
+ {
+ do {
+ //schedule_one_or_yield();
+ if ( ! try_executing_one())
+ {
+ return false;
+ }
+ } while (! pred());
+ return true;
+ }
+ };
+
+ }
+ using executors::executor;
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/executors/executor_adaptor.hpp b/src/third_party/boost-1.60.0/boost/thread/executors/executor_adaptor.hpp
new file mode 100644
index 00000000000..ca1a35f2d92
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/executors/executor_adaptor.hpp
@@ -0,0 +1,136 @@
+// Copyright (C) 2013,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)
+//
+// 2013/09 Vicente J. Botet Escriba
+// Adapt to boost from CCIA C++11 implementation
+
+#ifndef BOOST_THREAD_EXECUTORS_EXECUTOR_ADAPTOR_HPP
+#define BOOST_THREAD_EXECUTORS_EXECUTOR_ADAPTOR_HPP
+
+#include <boost/thread/detail/config.hpp>
+
+#include <boost/thread/executors/executor.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+namespace executors
+{
+ /**
+ * Polymorphic adaptor of a model of Executor to an executor.
+ */
+ template <typename Executor>
+ class executor_adaptor : public executor
+ {
+ Executor ex;
+ public:
+ /// type-erasure to store the works to do
+ typedef executor::work work;
+
+ /// executor is not copyable.
+ BOOST_THREAD_NO_COPYABLE(executor_adaptor)
+
+ /**
+ * executor_adaptor constructor
+ */
+#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template <typename ...Args>
+ executor_adaptor(BOOST_THREAD_RV_REF(Args) ... args) : ex(boost::forward<Args>(args)...) {}
+#else
+ /**
+ * executor_adaptor constructor
+ */
+ executor_adaptor() : ex() {}
+
+ template <typename A1>
+ executor_adaptor(
+ BOOST_THREAD_FWD_REF(A1) a1
+ ) :
+ ex(
+ boost::forward<A1>(a1)
+ ) {}
+ template <typename A1, typename A2>
+ executor_adaptor(
+ BOOST_THREAD_FWD_REF(A1) a1,
+ BOOST_THREAD_FWD_REF(A2) a2
+ ) :
+ ex(
+ boost::forward<A1>(a1),
+ boost::forward<A2>(a2)
+ ) {}
+ template <typename A1, typename A2, typename A3>
+ executor_adaptor(
+ BOOST_THREAD_FWD_REF(A1) a1,
+ BOOST_THREAD_FWD_REF(A2) a2,
+ BOOST_THREAD_FWD_REF(A3) a3
+ ) :
+ ex(
+ boost::forward<A1>(a1),
+ boost::forward<A2>(a2),
+ boost::forward<A3>(a3)
+ ) {}
+#endif
+ Executor& underlying_executor() { return ex; }
+
+ /**
+ * \b Effects: close the \c executor for submissions.
+ * The worker threads will work until there is no more closures to run.
+ */
+ void close() { ex.close(); }
+
+ /**
+ * \b Returns: whether the pool is closed for submissions.
+ */
+ bool closed() { return ex.closed(); }
+
+ /**
+ * \b Effects: The specified closure will be scheduled for execution at some point in the future.
+ * If invoked closure throws an exception the executor will call std::terminate, as is the case with threads.
+ *
+ * \b Synchronization: completion of closure on a particular thread happens before destruction of thread's thread local variables.
+ *
+ * \b Throws: \c sync_queue_is_closed if the thread pool is closed.
+ * Whatever exception that can be throw while storing the closure.
+ */
+ void submit(BOOST_THREAD_RV_REF(work) closure) {
+ return ex.submit(boost::move(closure));
+ }
+
+#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ template <typename Closure>
+ void submit(Closure & closure)
+ {
+ submit(work(closure));
+ }
+#endif
+ void submit(void (*closure)())
+ {
+ submit(work(closure));
+ }
+
+ template <typename Closure>
+ void submit(BOOST_THREAD_FWD_REF(Closure) closure)
+ {
+ //submit(work(boost::forward<Closure>(closure)));
+ work w((boost::forward<Closure>(closure)));
+ submit(boost::move(w));
+ }
+
+ /**
+ * Effects: try to execute one task.
+ * Returns: whether a task has been executed.
+ * Throws: whatever the current task constructor throws or the task() throws.
+ */
+ bool try_executing_one() { return ex.try_executing_one(); }
+
+ };
+}
+using executors::executor_adaptor;
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/executors/generic_executor_ref.hpp b/src/third_party/boost-1.60.0/boost/thread/executors/generic_executor_ref.hpp
new file mode 100644
index 00000000000..de270bcfed3
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/executors/generic_executor_ref.hpp
@@ -0,0 +1,213 @@
+// 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)
+//
+
+#ifndef BOOST_THREAD_EXECUTORS_GENERIC_EXECUTOR_REF_HPP
+#define BOOST_THREAD_EXECUTORS_GENERIC_EXECUTOR_REF_HPP
+
+#include <boost/thread/detail/config.hpp>
+
+#include <boost/thread/detail/delete.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/executors/executor.hpp>
+
+#include <boost/shared_ptr.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ namespace executors
+ {
+
+ template <class Executor>
+ class executor_ref : public executor
+ {
+ Executor& ex;
+ public:
+ /// type-erasure to store the works to do
+ typedef executors::work work;
+
+ /// executor is not copyable.
+ BOOST_THREAD_NO_COPYABLE(executor_ref)
+ executor_ref(Executor& ex) : ex(ex) {}
+
+ /**
+ * \par Effects
+ * Destroys the executor.
+ *
+ * \par Synchronization
+ * The completion of all the closures happen before the completion of the executor destructor.
+ */
+ ~executor_ref() {};
+
+ /**
+ * \par Effects
+ * Close the \c executor for submissions.
+ * The worker threads will work until there is no more closures to run.
+ */
+ void close() { ex.close(); }
+
+ /**
+ * \par Returns
+ * Whether the pool is closed for submissions.
+ */
+ bool closed() { return ex.closed(); }
+
+ /**
+ * \par Effects
+ * The specified closure will be scheduled for execution at some point in the future.
+ * If invoked closure throws an exception the executor will call std::terminate, as is the case with threads.
+ *
+ * \par Synchronization
+ * Ccompletion of closure on a particular thread happens before destruction of thread's thread local variables.
+ *
+ * \par Throws
+ * \c sync_queue_is_closed if the thread pool is closed.
+ * Whatever exception that can be throw while storing the closure.
+ */
+ void submit(BOOST_THREAD_RV_REF(work) closure) {
+ ex.submit(boost::move(closure));
+ }
+// void submit(work& closure) {
+// ex.submit(closure);
+// }
+
+
+ /**
+ * \par Effects
+ * Try to execute one task.
+ *
+ * \par Returns
+ * Whether a task has been executed.
+ *
+ * \par Throws
+ * Whatever the current task constructor throws or the task() throws.
+ */
+ bool try_executing_one() { return ex.try_executing_one(); }
+
+ };
+
+ class generic_executor_ref
+ {
+ shared_ptr<executor> ex;
+ public:
+ /// type-erasure to store the works to do
+ typedef executors::work work;
+
+ template<typename Executor>
+ generic_executor_ref(Executor& ex)
+ //: ex(make_shared<executor_ref<Executor> >(ex)) // todo check why this doesn't works with C++03
+ : ex( new executor_ref<Executor>(ex) )
+ {
+ }
+
+ //generic_executor_ref(generic_executor_ref const& other) noexcept {}
+ //generic_executor_ref& operator=(generic_executor_ref const& other) noexcept {}
+
+
+ /**
+ * \par Effects
+ * Close the \c executor for submissions.
+ * The worker threads will work until there is no more closures to run.
+ */
+ void close() { ex->close(); }
+
+ /**
+ * \par Returns
+ * Whether the pool is closed for submissions.
+ */
+ bool closed() { return ex->closed(); }
+
+ /**
+ * \par Requires
+ * \c Closure is a model of Callable(void()) and a model of CopyConstructible/MoveConstructible.
+ *
+ * \par Effects
+ * The specified closure will be scheduled for execution at some point in the future.
+ * If invoked closure throws an exception the thread pool will call std::terminate, as is the case with threads.
+ *
+ * \par Synchronization
+ * Completion of closure on a particular thread happens before destruction of thread's thread local variables.
+ *
+ * \par Throws
+ * \c sync_queue_is_closed if the thread pool is closed.
+ * Whatever exception that can be throw while storing the closure.
+ */
+
+ void submit(BOOST_THREAD_RV_REF(work) closure)
+ {
+ ex->submit(boost::move(closure));
+ }
+
+#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ template <typename Closure>
+ void submit(Closure & closure)
+ {
+ //work w ((closure));
+ //submit(boost::move(w));
+ submit(work(closure));
+ }
+#endif
+ void submit(void (*closure)())
+ {
+ work w ((closure));
+ submit(boost::move(w));
+ //submit(work(closure));
+ }
+
+ template <typename Closure>
+ void submit(BOOST_THREAD_FWD_REF(Closure) closure)
+ {
+ work w((boost::forward<Closure>(closure)));
+ submit(boost::move(w));
+ }
+
+// size_t num_pending_closures() const
+// {
+// return ex->num_pending_closures();
+// }
+
+ /**
+ * \par Effects
+ * Try to execute one task.
+ *
+ * \par Returns
+ * Whether a task has been executed.
+ *
+ * \par Throws
+ * Whatever the current task constructor throws or the task() throws.
+ */
+ bool try_executing_one() { return ex->try_executing_one(); }
+
+ /**
+ * \par Requires
+ * This must be called from an scheduled task.
+ *
+ * \par Effects
+ * reschedule functions until pred()
+ */
+ template <typename Pred>
+ bool reschedule_until(Pred const& pred)
+ {
+ do {
+ //schedule_one_or_yield();
+ if ( ! try_executing_one())
+ {
+ return false;
+ }
+ } while (! pred());
+ return true;
+ }
+
+ };
+ }
+ using executors::executor_ref;
+ using executors::generic_executor_ref;
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/executors/inline_executor.hpp b/src/third_party/boost-1.60.0/boost/thread/executors/inline_executor.hpp
new file mode 100644
index 00000000000..5dd523184ed
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/executors/inline_executor.hpp
@@ -0,0 +1,171 @@
+// 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)
+//
+// 2013/11 Vicente J. Botet Escriba
+// first implementation of a simple serial scheduler.
+
+#ifndef BOOST_THREAD_INLINE_EXECUTOR_HPP
+#define BOOST_THREAD_INLINE_EXECUTOR_HPP
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/detail/delete.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/executors/work.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+namespace executors
+{
+ class inline_executor
+ {
+ public:
+ /// type-erasure to store the works to do
+ typedef executors::work work;
+ bool closed_;
+ mutable mutex mtx_;
+ /**
+ * Effects: try to execute one task.
+ * Returns: whether a task has been executed.
+ * Throws: whatever the current task constructor throws or the task() throws.
+ */
+ bool try_executing_one()
+ {
+ return false;
+ }
+
+ public:
+ /// inline_executor is not copyable.
+ BOOST_THREAD_NO_COPYABLE(inline_executor)
+
+ /**
+ * \b Effects: creates a inline executor that runs closures immediately.
+ *
+ * \b Throws: Nothing.
+ */
+ inline_executor()
+ : closed_(false)
+ {
+ }
+ /**
+ * \b Effects: Destroys the inline executor.
+ *
+ * \b Synchronization: The completion of all the closures happen before the completion of the \c inline_executor destructor.
+ */
+ ~inline_executor()
+ {
+ // signal to all the worker thread that there will be no more submissions.
+ close();
+ }
+
+ /**
+ * \b Effects: close the \c inline_executor for submissions.
+ * The loop will work until there is no more closures to run.
+ */
+ void close()
+ {
+ lock_guard<mutex> lk(mtx_);
+ closed_ = true;
+ }
+
+ /**
+ * \b Returns: whether the pool is closed for submissions.
+ */
+ bool closed(lock_guard<mutex>& )
+ {
+ return closed_;
+ }
+ bool closed()
+ {
+ lock_guard<mutex> lk(mtx_);
+ return closed(lk);
+ }
+
+ /**
+ * \b Requires: \c Closure is a model of \c Callable(void()) and a model of \c CopyConstructible/MoveConstructible.
+ *
+ * \b Effects: The specified \c closure will be scheduled for execution at some point in the future.
+ * If invoked closure throws an exception the \c inline_executor will call \c std::terminate, as is the case with threads.
+ *
+ * \b Synchronization: completion of \c closure on a particular thread happens before destruction of thread's thread local variables.
+ *
+ * \b Throws: \c sync_queue_is_closed if the thread pool is closed.
+ * Whatever exception that can be throw while storing the closure.
+ */
+
+#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ template <typename Closure>
+ void submit(Closure & closure)
+ {
+ {
+ lock_guard<mutex> lk(mtx_);
+ if (closed(lk)) BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
+ }
+ try
+ {
+ closure();
+ }
+ catch (...)
+ {
+ std::terminate();
+ return;
+ }
+ }
+#endif
+ void submit(void (*closure)())
+ {
+ {
+ lock_guard<mutex> lk(mtx_);
+ if (closed(lk)) BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
+ }
+ try
+ {
+ closure();
+ }
+ catch (...)
+ {
+ std::terminate();
+ return;
+ }
+ }
+
+ template <typename Closure>
+ void submit(BOOST_THREAD_FWD_REF(Closure) closure)
+ {
+ {
+ lock_guard<mutex> lk(mtx_);
+ if (closed(lk)) BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
+ }
+ try
+ {
+ closure();
+ }
+ catch (...)
+ {
+ std::terminate();
+ return;
+ }
+ }
+
+ /**
+ * \b Requires: This must be called from an scheduled task.
+ *
+ * \b Effects: reschedule functions until pred()
+ */
+ template <typename Pred>
+ bool reschedule_until(Pred const& )
+ {
+ return false;
+ }
+
+ };
+}
+using executors::inline_executor;
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/executors/loop_executor.hpp b/src/third_party/boost-1.60.0/boost/thread/executors/loop_executor.hpp
new file mode 100644
index 00000000000..b08ff76f575
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/executors/loop_executor.hpp
@@ -0,0 +1,205 @@
+// Copyright (C) 2013,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)
+//
+// 2013/11 Vicente J. Botet Escriba
+// first implementation of a simple user scheduler.
+// 2013/11 Vicente J. Botet Escriba
+// rename loop_executor.
+
+#ifndef BOOST_THREAD_EXECUTORS_LOOP_EXECUTOR_HPP
+#define BOOST_THREAD_EXECUTORS_LOOP_EXECUTOR_HPP
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/detail/delete.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/concurrent_queues/sync_queue.hpp>
+#include <boost/thread/executors/work.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+namespace executors
+{
+
+ class loop_executor
+ {
+ public:
+ /// type-erasure to store the works to do
+ typedef executors::work work;
+ private:
+ /// the thread safe work queue
+ concurrent::sync_queue<work > work_queue;
+
+ public:
+ /**
+ * Effects: try to execute one task.
+ * Returns: whether a task has been executed.
+ * Throws: whatever the current task constructor throws or the task() throws.
+ */
+ bool try_executing_one()
+ {
+ work task;
+ try
+ {
+ if (work_queue.try_pull(task) == queue_op_status::success)
+ {
+ task();
+ return true;
+ }
+ return false;
+ }
+ catch (...)
+ {
+ std::terminate();
+ //return false;
+ }
+ }
+ private:
+ /**
+ * Effects: schedule one task or yields
+ * Throws: whatever the current task constructor throws or the task() throws.
+ */
+ void schedule_one_or_yield()
+ {
+ if ( ! try_executing_one())
+ {
+ this_thread::yield();
+ }
+ }
+
+
+
+
+ public:
+ /// loop_executor is not copyable.
+ BOOST_THREAD_NO_COPYABLE(loop_executor)
+
+ /**
+ * \b Effects: creates a thread pool that runs closures using one of its closure-executing methods.
+ *
+ * \b Throws: Whatever exception is thrown while initializing the needed resources.
+ */
+ loop_executor()
+ {
+ }
+ /**
+ * \b Effects: Destroys the thread pool.
+ *
+ * \b Synchronization: The completion of all the closures happen before the completion of the \c loop_executor destructor.
+ */
+ ~loop_executor()
+ {
+ // signal to all the worker thread that there will be no more submissions.
+ close();
+ }
+
+ /**
+ * The main loop of the worker thread
+ */
+ void loop()
+ {
+ while (!closed())
+ {
+ schedule_one_or_yield();
+ }
+ while (try_executing_one())
+ {
+ }
+ }
+
+ /**
+ * \b Effects: close the \c loop_executor for submissions.
+ * The loop will work until there is no more closures to run.
+ */
+ void close()
+ {
+ work_queue.close();
+ }
+
+ /**
+ * \b Returns: whether the pool is closed for submissions.
+ */
+ bool closed()
+ {
+ return work_queue.closed();
+ }
+
+ /**
+ * \b Requires: \c Closure is a model of \c Callable(void()) and a model of \c CopyConstructible/MoveConstructible.
+ *
+ * \b Effects: The specified \c closure will be scheduled for execution at some point in the future.
+ * If invoked closure throws an exception the \c loop_executor will call \c std::terminate, as is the case with threads.
+ *
+ * \b Synchronization: completion of \c closure on a particular thread happens before destruction of thread's thread local variables.
+ *
+ * \b Throws: \c sync_queue_is_closed if the thread pool is closed.
+ * Whatever exception that can be throw while storing the closure.
+ */
+ void submit(BOOST_THREAD_RV_REF(work) closure) {
+ work_queue.push(boost::move(closure));
+ }
+
+#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ template <typename Closure>
+ void submit(Closure & closure)
+ {
+ submit(work(closure));
+ }
+#endif
+
+ void submit(void (*closure)())
+ {
+ submit(work(closure));
+ }
+
+ template <typename Closure>
+ void submit(BOOST_THREAD_FWD_REF(Closure) closure)
+ {
+ //work_queue.push(work(boost::forward<Closure>(closure)));
+ work w((boost::forward<Closure>(closure)));
+ submit(boost::move(w));
+ }
+
+ /**
+ * \b Requires: This must be called from an scheduled task.
+ *
+ * \b Effects: reschedule functions until pred()
+ */
+ template <typename Pred>
+ bool reschedule_until(Pred const& pred)
+ {
+ do {
+ if ( ! try_executing_one())
+ {
+ return false;
+ }
+ } while (! pred());
+ return true;
+ }
+
+ /**
+ * run queued closures
+ */
+ void run_queued_closures()
+ {
+ sync_queue<work>::underlying_queue_type q = work_queue.underlying_queue();
+ while (! q.empty())
+ {
+ work& task = q.front();
+ task();
+ q.pop_front();
+ }
+ }
+
+ };
+}
+using executors::loop_executor;
+
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/executors/scheduled_thread_pool.hpp b/src/third_party/boost-1.60.0/boost/thread/executors/scheduled_thread_pool.hpp
new file mode 100644
index 00000000000..408013b283e
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/executors/scheduled_thread_pool.hpp
@@ -0,0 +1,48 @@
+// 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)
+//
+
+#ifndef BOOST_THREAD_EXECUTORS_SCHEDULED_THREAD_POOL_HPP
+#define BOOST_THREAD_EXECUTORS_SCHEDULED_THREAD_POOL_HPP
+
+#include <boost/thread/executors/detail/scheduled_executor_base.hpp>
+
+namespace boost
+{
+namespace executors
+{
+
+ class scheduled_thread_pool : public detail::scheduled_executor_base<>
+ {
+ private:
+ thread_group _workers;
+ public:
+
+ scheduled_thread_pool(size_t num_threads) : super()
+ {
+ for(size_t i = 0; i < num_threads; i++)
+ {
+ _workers.create_thread(bind(&super::loop, this));
+ }
+ }
+
+ ~scheduled_thread_pool()
+ {
+ this->close();
+ _workers.join_all();
+ }
+
+ private:
+ typedef detail::scheduled_executor_base<> super;
+ }; //end class
+
+} //end executors namespace
+
+using executors::scheduled_thread_pool;
+
+} //end boost
+#endif
+
diff --git a/src/third_party/boost-1.60.0/boost/thread/executors/scheduler.hpp b/src/third_party/boost-1.60.0/boost/thread/executors/scheduler.hpp
new file mode 100644
index 00000000000..5796a7d3947
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/executors/scheduler.hpp
@@ -0,0 +1,271 @@
+// 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)
+//
+
+#ifndef BOOST_THREAD_EXECUTORS_SCHEDULER_HPP
+#define BOOST_THREAD_EXECUTORS_SCHEDULER_HPP
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/executors/detail/scheduled_executor_base.hpp>
+
+#include <boost/chrono/time_point.hpp>
+#include <boost/chrono/duration.hpp>
+#include <boost/chrono/system_clocks.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ namespace executors
+ {
+ /// Wraps the reference to an executor and a function to make a work that submit the function using the executor.
+ template <class Executor, class Function>
+ class resubmitter
+ {
+ public:
+ resubmitter(Executor& ex, Function funct) :
+ ex(ex),
+ funct(boost::move(funct))
+ {}
+
+ void operator()()
+ {
+ ex.submit(funct);
+ }
+
+ private:
+ Executor& ex;
+ Function funct;
+ };
+
+ /// resubmitter factory
+ template <class Executor, class Function>
+ resubmitter<Executor, typename decay<Function>::type>
+ resubmit(Executor& ex, BOOST_THREAD_FWD_REF(Function) funct) {
+ return resubmitter<Executor, typename decay<Function>::type >(ex, boost::move(funct));
+ }
+
+ /// Wraps references to a @c Scheduler and an @c Executor providing an @c Executor that
+ /// resubmit the function using the referenced Executor at a given @c time_point known at construction.
+ template <class Scheduler, class Executor>
+ class resubmit_at_executor
+ {
+ public:
+ typedef typename Scheduler::clock clock;
+ typedef typename Scheduler::work work;
+
+ template <class Duration>
+ resubmit_at_executor(Scheduler& sch, Executor& ex, chrono::time_point<clock, Duration> const& tp) :
+ sch(sch),
+ ex(ex),
+ tp(tp),
+ is_closed(false)
+ {
+ }
+
+ ~resubmit_at_executor()
+ {
+ close();
+ }
+
+ template <class Work>
+ void submit(BOOST_THREAD_FWD_REF(Work) w)
+ {
+ if (closed())
+ {
+ BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
+ }
+ sch.submit_at(resubmit(ex,boost::forward<Work>(w)), tp);
+ }
+
+ Executor& underlying_executor()
+ {
+ return ex;
+ }
+ Scheduler& underlying_scheduler()
+ {
+ return sch;
+ }
+
+ void close()
+ {
+ is_closed = true;
+ }
+
+ bool closed()
+ {
+ return is_closed || sch.closed() || ex.closed();
+ }
+
+ private:
+ Scheduler& sch;
+ Executor& ex;
+ typename clock::time_point tp;
+ bool is_closed;
+ };
+
+
+ /// Expression template helper storing a pair of references to an @c Scheduler and an @c Executor
+ /// It provides factory helper functions such as at/after that convert these a pair of @c Scheduler @c Executor
+ /// into an new @c Executor that submit the work using the referenced @c Executor at/after a specific time/duration
+ /// respectively, using the referenced @Scheduler.
+ template <class Scheduler, class Executor>
+ class scheduler_executor_wrapper
+ {
+ public:
+ typedef typename Scheduler::clock clock;
+ typedef typename Scheduler::work work;
+ typedef resubmit_at_executor<Scheduler, Executor> the_executor;
+
+ scheduler_executor_wrapper(Scheduler& sch, Executor& ex) :
+ sch(sch),
+ ex(ex)
+ {}
+
+ ~scheduler_executor_wrapper()
+ {
+ }
+
+ Executor& underlying_executor()
+ {
+ return ex;
+ }
+ Scheduler& underlying_scheduler()
+ {
+ return sch;
+ }
+
+ template <class Rep, class Period>
+ the_executor after(chrono::duration<Rep,Period> const& rel_time)
+ {
+ return at(clock::now() + rel_time );
+ }
+
+ template <class Duration>
+ the_executor at(chrono::time_point<clock,Duration> const& abs_time)
+ {
+ return the_executor(sch, ex, abs_time);
+ }
+
+ private:
+ Scheduler& sch;
+ Executor& ex;
+ }; //end class
+
+ /// Wraps a reference to a @c Scheduler providing an @c Executor that
+ /// run the function at a given @c time_point known at construction.
+ template <class Scheduler>
+ class at_executor
+ {
+ public:
+ typedef typename Scheduler::clock clock;
+ typedef typename Scheduler::work work;
+ typedef typename clock::time_point time_point;
+
+ template <class Duration>
+ at_executor(Scheduler& sch, chrono::time_point<clock,Duration> const& tp) :
+ sch(sch),
+ tp(tp),
+ is_closed(false)
+ {}
+
+ ~at_executor()
+ {
+ close();
+ }
+
+ Scheduler& underlying_scheduler()
+ {
+ return sch;
+ }
+
+ void close()
+ {
+ is_closed = true;
+ }
+
+ bool closed()
+ {
+ return is_closed || sch.closed();
+ }
+
+ template <class Work>
+ void submit(BOOST_THREAD_FWD_REF(Work) w)
+ {
+ if (closed())
+ {
+ BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
+ }
+ sch.submit_at(boost::forward<Work>(w), tp);
+ }
+
+ template <class Executor>
+ resubmit_at_executor<Scheduler, Executor> on(Executor& ex)
+ {
+ return resubmit_at_executor<Scheduler, Executor>(sch, ex, tp);
+ }
+
+ private:
+ Scheduler& sch;
+ time_point tp;
+ bool is_closed;
+ }; //end class
+
+ /// A @c Scheduler using a specific thread. Note that a Scheduler is not an Executor.
+ /// It provides factory helper functions such as at/after that convert a @c Scheduler into an @c Executor
+ /// that submit the work at/after a specific time/duration respectively.
+ template <class Clock = chrono::steady_clock>
+ class scheduler : public detail::scheduled_executor_base<Clock>
+ {
+ public:
+ typedef typename detail::scheduled_executor_base<Clock>::work work;
+
+ typedef Clock clock;
+
+ scheduler()
+ : super(),
+ thr(&super::loop, this) {}
+
+ ~scheduler()
+ {
+ this->close();
+ thr.join();
+ }
+ template <class Ex>
+ scheduler_executor_wrapper<scheduler, Ex> on(Ex& ex)
+ {
+ return scheduler_executor_wrapper<scheduler, Ex>(*this, ex);
+ }
+
+ template <class Rep, class Period>
+ at_executor<scheduler> after(chrono::duration<Rep,Period> const& rel_time)
+ {
+ return at(rel_time + clock::now());
+ }
+
+ template <class Duration>
+ at_executor<scheduler> at(chrono::time_point<clock,Duration> const& tp)
+ {
+ return at_executor<scheduler>(*this, tp);
+ }
+
+ private:
+ typedef detail::scheduled_executor_base<Clock> super;
+ thread thr;
+ };
+
+
+ }
+ using executors::resubmitter;
+ using executors::resubmit;
+ using executors::resubmit_at_executor;
+ using executors::scheduler_executor_wrapper;
+ using executors::at_executor;
+ using executors::scheduler;
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/executors/scheduling_adaptor.hpp b/src/third_party/boost-1.60.0/boost/thread/executors/scheduling_adaptor.hpp
new file mode 100644
index 00000000000..ac0a0acbce8
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/executors/scheduling_adaptor.hpp
@@ -0,0 +1,51 @@
+// 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)
+//
+
+#ifndef BOOST_THREAD_EXECUTORS_SCHEDULING_ADAPTOR_HPP
+#define BOOST_THREAD_EXECUTORS_SCHEDULING_ADAPTOR_HPP
+
+#include <boost/thread/executors/detail/scheduled_executor_base.hpp>
+
+namespace boost
+{
+namespace executors
+{
+
+ template <typename Executor>
+ class scheduling_adpator : public detail::scheduled_executor_base<>
+ {
+ private:
+ Executor& _exec;
+ thread _scheduler;
+ public:
+
+ scheduling_adpator(Executor& ex)
+ : super(),
+ _exec(ex),
+ _scheduler(&super::loop, this) {}
+
+ ~scheduling_adpator()
+ {
+ this->close();
+ _scheduler.join();
+ }
+
+ Executor& underlying_executor()
+ {
+ return _exec;
+ }
+
+ private:
+ typedef detail::scheduled_executor_base<> super;
+ }; //end class
+
+} //end executors
+
+ using executors::scheduling_adpator;
+
+} //end boost
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/executors/serial_executor.hpp b/src/third_party/boost-1.60.0/boost/thread/executors/serial_executor.hpp
new file mode 100644
index 00000000000..6d7ed9be97b
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/executors/serial_executor.hpp
@@ -0,0 +1,216 @@
+// 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)
+//
+// 2013/11 Vicente J. Botet Escriba
+// first implementation of a simple serial scheduler.
+
+#ifndef BOOST_THREAD_SERIAL_EXECUTOR_HPP
+#define BOOST_THREAD_SERIAL_EXECUTOR_HPP
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/detail/delete.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/concurrent_queues/sync_queue.hpp>
+#include <boost/thread/executors/work.hpp>
+#include <boost/thread/executors/generic_executor_ref.hpp>
+#include <boost/thread/future.hpp>
+#include <boost/thread/scoped_thread.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+namespace executors
+{
+ class serial_executor
+ {
+ public:
+ /// type-erasure to store the works to do
+ typedef executors::work work;
+ private:
+ typedef scoped_thread<> thread_t;
+
+ /// the thread safe work queue
+ concurrent::sync_queue<work > work_queue;
+ generic_executor_ref ex;
+ thread_t thr;
+
+ struct try_executing_one_task {
+ work& task;
+ boost::promise<void> &p;
+ try_executing_one_task(work& task, boost::promise<void> &p)
+ : task(task), p(p) {}
+ void operator()() {
+ try {
+ task();
+ p.set_value();
+ } catch (...)
+ {
+ p.set_exception(current_exception());
+ }
+ }
+ };
+ public:
+ /**
+ * \par Returns
+ * The underlying executor wrapped on a generic executor reference.
+ */
+ generic_executor_ref& underlying_executor() BOOST_NOEXCEPT { return ex; }
+
+ /**
+ * Effects: try to execute one task.
+ * Returns: whether a task has been executed.
+ * Throws: whatever the current task constructor throws or the task() throws.
+ */
+ bool try_executing_one()
+ {
+ work task;
+ try
+ {
+ if (work_queue.try_pull(task) == queue_op_status::success)
+ {
+ boost::promise<void> p;
+ try_executing_one_task tmp(task,p);
+ ex.submit(tmp);
+ p.get_future().wait();
+ return true;
+ }
+ return false;
+ }
+ catch (...)
+ {
+ std::terminate();
+ //return false;
+ }
+ }
+ private:
+ /**
+ * Effects: schedule one task or yields
+ * Throws: whatever the current task constructor throws or the task() throws.
+ */
+ void schedule_one_or_yield()
+ {
+ if ( ! try_executing_one())
+ {
+ this_thread::yield();
+ }
+ }
+
+ /**
+ * The main loop of the worker thread
+ */
+ void worker_thread()
+ {
+ while (!closed())
+ {
+ schedule_one_or_yield();
+ }
+ while (try_executing_one())
+ {
+ }
+ }
+
+ public:
+ /// serial_executor is not copyable.
+ BOOST_THREAD_NO_COPYABLE(serial_executor)
+
+ /**
+ * \b Effects: creates a thread pool that runs closures using one of its closure-executing methods.
+ *
+ * \b Throws: Whatever exception is thrown while initializing the needed resources.
+ */
+ template <class Executor>
+ serial_executor(Executor& ex)
+ : ex(ex), thr(&serial_executor::worker_thread, this)
+ {
+ }
+ /**
+ * \b Effects: Destroys the thread pool.
+ *
+ * \b Synchronization: The completion of all the closures happen before the completion of the \c serial_executor destructor.
+ */
+ ~serial_executor()
+ {
+ // signal to the worker thread that there will be no more submissions.
+ close();
+ }
+
+ /**
+ * \b Effects: close the \c serial_executor for submissions.
+ * The loop will work until there is no more closures to run.
+ */
+ void close()
+ {
+ work_queue.close();
+ }
+
+ /**
+ * \b Returns: whether the pool is closed for submissions.
+ */
+ bool closed()
+ {
+ return work_queue.closed();
+ }
+
+ /**
+ * \b Requires: \c Closure is a model of \c Callable(void()) and a model of \c CopyConstructible/MoveConstructible.
+ *
+ * \b Effects: The specified \c closure will be scheduled for execution at some point in the future.
+ * If invoked closure throws an exception the \c serial_executor will call \c std::terminate, as is the case with threads.
+ *
+ * \b Synchronization: completion of \c closure on a particular thread happens before destruction of thread's thread local variables.
+ *
+ * \b Throws: \c sync_queue_is_closed if the thread pool is closed.
+ * Whatever exception that can be throw while storing the closure.
+ */
+ void submit(BOOST_THREAD_RV_REF(work) closure)
+ {
+ work_queue.push(boost::move(closure));
+ }
+
+#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ template <typename Closure>
+ void submit(Closure & closure)
+ {
+ submit(work(closure));
+ }
+#endif
+ void submit(void (*closure)())
+ {
+ submit(work(closure));
+ }
+
+ template <typename Closure>
+ void submit(BOOST_THREAD_FWD_REF(Closure) closure)
+ {
+ work w((boost::forward<Closure>(closure)));
+ submit(boost::move(w));
+ }
+
+ /**
+ * \b Requires: This must be called from an scheduled task.
+ *
+ * \b Effects: reschedule functions until pred()
+ */
+ template <typename Pred>
+ bool reschedule_until(Pred const& pred)
+ {
+ do {
+ if ( ! try_executing_one())
+ {
+ return false;
+ }
+ } while (! pred());
+ return true;
+ }
+
+ };
+}
+using executors::serial_executor;
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/executors/serial_executor_cont.hpp b/src/third_party/boost-1.60.0/boost/thread/executors/serial_executor_cont.hpp
new file mode 100644
index 00000000000..91087890be6
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/executors/serial_executor_cont.hpp
@@ -0,0 +1,170 @@
+// Copyright (C) 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)
+//
+// 2013/11 Vicente J. Botet Escriba
+// first implementation of a simple serial scheduler.
+
+#ifndef BOOST_THREAD_SERIAL_EXECUTOR_CONT_HPP
+#define BOOST_THREAD_SERIAL_EXECUTOR_CONT_HPP
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/detail/delete.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/concurrent_queues/sync_queue.hpp>
+#include <boost/thread/executors/work.hpp>
+#include <boost/thread/executors/generic_executor_ref.hpp>
+#include <boost/thread/future.hpp>
+#include <boost/thread/scoped_thread.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+namespace executors
+{
+ class serial_executor_cont
+ {
+ public:
+ /// type-erasure to store the works to do
+ typedef executors::work work;
+ private:
+
+ generic_executor_ref ex_;
+ future<void> fut_; // protected by mtx_
+ bool closed_; // protected by mtx_
+ mutex mtx_;
+
+ struct continuation {
+ work task;
+ template <class X>
+ struct result {
+ typedef void type;
+ };
+ continuation(BOOST_THREAD_RV_REF(work) tsk)
+ : task(boost::move(tsk)) {}
+ void operator()(future<void> f)
+ {
+ try {
+ task();
+ } catch (...) {
+ std::terminate();
+ }
+ }
+ };
+
+ bool closed(lock_guard<mutex>&) const
+ {
+ return closed_;
+ }
+ public:
+ /**
+ * \par Returns
+ * The underlying executor wrapped on a generic executor reference.
+ */
+ generic_executor_ref& underlying_executor() BOOST_NOEXCEPT { return ex_; }
+
+ /// serial_executor_cont is not copyable.
+ BOOST_THREAD_NO_COPYABLE(serial_executor_cont)
+
+ /**
+ * \b Effects: creates a serial executor that runs closures in fifo order using one the associated executor.
+ *
+ * \b Throws: Whatever exception is thrown while initializing the needed resources.
+ *
+ * \b Notes:
+ * * The lifetime of the associated executor must outlive the serial executor.
+ * * The current implementation doesn't support submission from synchronous continuation, that is,
+ * - the executor must execute the continuation asynchronously or
+ * - the continuation can not submit to this serial executor.
+ */
+ template <class Executor>
+ serial_executor_cont(Executor& ex)
+ : ex_(ex), fut_(make_ready_future()), closed_(false)
+ {
+ }
+ /**
+ * \b Effects: Destroys the thread pool.
+ *
+ * \b Synchronization: The completion of all the closures happen before the completion of the \c serial_executor_cont destructor.
+ */
+ ~serial_executor_cont()
+ {
+ // signal to the worker thread that there will be no more submissions.
+ close();
+ }
+
+ /**
+ * \b Effects: close the \c serial_executor_cont for submissions.
+ * The loop will work until there is no more closures to run.
+ */
+ void close()
+ {
+ lock_guard<mutex> lk(mtx_);
+ closed_ = true;;
+ }
+
+ /**
+ * \b Returns: whether the pool is closed for submissions.
+ */
+ bool closed()
+ {
+ lock_guard<mutex> lk(mtx_);
+ return closed(lk);
+ }
+
+ /**
+ * Effects: none.
+ * Returns: always false.
+ * Throws: No.
+ * Remark: A serial executor can not execute one of its pending tasks as the tasks depends on the other tasks.
+ */
+ bool try_executing_one()
+ {
+ return false;
+ }
+
+ /**
+ * \b Requires: \c Closure is a model of \c Callable(void()) and a model of \c CopyConstructible/MoveConstructible.
+ *
+ * \b Effects: The specified \c closure will be scheduled for execution after the last submitted closure finish.
+ * If the invoked closure throws an exception the \c serial_executor_cont will call \c std::terminate, as is the case with threads.
+ *
+ * \b Throws: \c sync_queue_is_closed if the executor is closed.
+ * Whatever exception that can be throw while storing the closure.
+ *
+ */
+
+#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ template <typename Closure>
+ void submit(Closure & closure)
+ {
+ lock_guard<mutex> lk(mtx_);
+ if (closed(lk)) BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
+ fut_ = fut_.then(ex_, continuation(work(closure)));
+ }
+#endif
+ void submit(void (*closure)())
+ {
+ lock_guard<mutex> lk(mtx_);
+ if (closed(lk)) BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
+ fut_ = fut_.then(ex_, continuation(work(closure)));
+ }
+
+ template <typename Closure>
+ void submit(BOOST_THREAD_FWD_REF(Closure) closure)
+ {
+ lock_guard<mutex> lk(mtx_);
+ if (closed(lk)) BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
+ fut_ = fut_.then(ex_, continuation(work(boost::forward<Closure>(closure))));
+ }
+
+ };
+}
+using executors::serial_executor_cont;
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/executors/thread_executor.hpp b/src/third_party/boost-1.60.0/boost/thread/executors/thread_executor.hpp
new file mode 100644
index 00000000000..c9f49a7b62f
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/executors/thread_executor.hpp
@@ -0,0 +1,157 @@
+// 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)
+//
+// 2014/01 Vicente J. Botet Escriba
+// first implementation of a thread_executor.
+
+#ifndef BOOST_THREAD_THREAD_EXECUTOR_HPP
+#define BOOST_THREAD_THREAD_EXECUTOR_HPP
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/detail/delete.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/executors/work.hpp>
+#include <boost/thread/executors/executor.hpp>
+#include <boost/thread/thread_only.hpp>
+#include <boost/thread/scoped_thread.hpp>
+#include <boost/thread/csbl/vector.hpp>
+#include <boost/thread/concurrent_queues/queue_op_status.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+namespace executors
+{
+ class thread_executor
+ {
+ public:
+ /// type-erasure to store the works to do
+ typedef executors::work work;
+ bool closed_;
+ typedef scoped_thread<> thread_t;
+ typedef csbl::vector<thread_t> threads_type;
+ threads_type threads_;
+ mutable mutex mtx_;
+
+ /**
+ * Effects: try to execute one task.
+ * Returns: whether a task has been executed.
+ * Throws: whatever the current task constructor throws or the task() throws.
+ */
+ bool try_executing_one()
+ {
+ return false;
+ }
+
+ public:
+ /// thread_executor is not copyable.
+ BOOST_THREAD_NO_COPYABLE(thread_executor)
+
+ /**
+ * \b Effects: creates a inline executor that runs closures immediately.
+ *
+ * \b Throws: Nothing.
+ */
+ thread_executor()
+ : closed_(false)
+ {
+ }
+ /**
+ * \b Effects: Waits for closures (if any) to complete, then joins and destroys the threads.
+ *
+ * \b Synchronization: The completion of all the closures happen before the completion of the \c thread_executor destructor.
+ */
+ ~thread_executor()
+ {
+ // signal to all the worker thread that there will be no more submissions.
+ close();
+ // all the scoped threads will join before destroying
+ }
+
+ /**
+ * \b Effects: close the \c thread_executor for submissions.
+ * The loop will work until there is no more closures to run.
+ */
+ void close()
+ {
+ lock_guard<mutex> lk(mtx_);
+ closed_ = true;
+ }
+
+ /**
+ * \b Returns: whether the pool is closed for submissions.
+ */
+ bool closed(lock_guard<mutex>& )
+ {
+ return closed_;
+ }
+ bool closed()
+ {
+ lock_guard<mutex> lk(mtx_);
+ return closed(lk);
+ }
+
+ /**
+ * \b Requires: \c Closure is a model of \c Callable(void()) and a model of \c CopyConstructible/MoveConstructible.
+ *
+ * \b Effects: The specified \c closure will be scheduled for execution at some point in the future.
+ * If invoked closure throws an exception the \c thread_executor will call \c std::terminate, as is the case with threads.
+ *
+ * \b Synchronization: completion of \c closure on a particular thread happens before destruction of thread's thread local variables.
+ *
+ * \b Throws: \c sync_queue_is_closed if the thread pool is closed.
+ * Whatever exception that can be throw while storing the closure.
+ */
+
+#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ template <typename Closure>
+ void submit(Closure & closure)
+ {
+ lock_guard<mutex> lk(mtx_);
+ if (closed(lk)) BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
+ threads_.reserve(threads_.size() + 1);
+ thread th(closure);
+ threads_.push_back(thread_t(boost::move(th)));
+ }
+#endif
+ void submit(void (*closure)())
+ {
+ lock_guard<mutex> lk(mtx_);
+ if (closed(lk)) BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
+ threads_.reserve(threads_.size() + 1);
+ thread th(closure);
+ threads_.push_back(thread_t(boost::move(th)));
+ }
+
+ template <typename Closure>
+ void submit(BOOST_THREAD_FWD_REF(Closure) closure)
+ {
+ lock_guard<mutex> lk(mtx_);
+ if (closed(lk)) BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
+ threads_.reserve(threads_.size() + 1);
+ thread th(boost::forward<Closure>(closure));
+ threads_.push_back(thread_t(boost::move(th)));
+ }
+
+ /**
+ * \b Requires: This must be called from an scheduled task.
+ *
+ * \b Effects: reschedule functions until pred()
+ */
+ template <typename Pred>
+ bool reschedule_until(Pred const&)
+ {
+ return false;
+ }
+
+ };
+}
+using executors::thread_executor;
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/executors/work.hpp b/src/third_party/boost-1.60.0/boost/thread/executors/work.hpp
new file mode 100644
index 00000000000..bdaf7651b92
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/executors/work.hpp
@@ -0,0 +1,30 @@
+// (C) Copyright 2013,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)
+
+#ifndef BOOST_THREAD_EXECUTORS_WORK_HPP
+#define BOOST_THREAD_EXECUTORS_WORK_HPP
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/detail/nullary_function.hpp>
+#include <boost/thread/csbl/functional.hpp>
+
+namespace boost
+{
+ namespace executors
+ {
+ typedef detail::nullary_function<void()> work;
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ typedef detail::nullary_function<void()> work_pq;
+ //typedef csbl::function<void()> work_pq;
+#else
+ typedef csbl::function<void()> work_pq;
+#endif
+ }
+} // namespace boost
+
+
+#endif // BOOST_THREAD_EXECUTORS_WORK_HPP
diff --git a/src/third_party/boost-1.60.0/boost/thread/experimental/config/inline_namespace.hpp b/src/third_party/boost-1.60.0/boost/thread/experimental/config/inline_namespace.hpp
new file mode 100644
index 00000000000..9c3b081fbe4
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/experimental/config/inline_namespace.hpp
@@ -0,0 +1,23 @@
+#ifndef BOOST_THREAD_EXPERIMENTAL_CONFIG_INLINE_NAMESPACE_HPP
+#define BOOST_THREAD_EXPERIMENTAL_CONFIG_INLINE_NAMESPACE_HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2014. Distributed under the 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 http://www.boost.org/libs/thread for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/config.hpp>
+
+#if !defined(BOOST_NO_CXX11_INLINE_NAMESPACES)
+# define BOOST_THREAD_INLINE_NAMESPACE(name) inline namespace name
+#else
+# define BOOST_THREAD_INLINE_NAMESPACE(name) namespace name
+#endif
+
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/experimental/exception_list.hpp b/src/third_party/boost-1.60.0/boost/thread/experimental/exception_list.hpp
new file mode 100644
index 00000000000..748bfa85ee7
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/experimental/exception_list.hpp
@@ -0,0 +1,16 @@
+#ifndef BOOST_THREAD_EXPERIMENTAL_EXCEPTION_LIST_HPP
+#define BOOST_THREAD_EXPERIMENTAL_EXCEPTION_LIST_HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2014. Distributed under the 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 http://www.boost.org/libs/thread for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/thread/experimental/parallel/v1/exception_list.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/experimental/parallel/v1/exception_list.hpp b/src/third_party/boost-1.60.0/boost/thread/experimental/parallel/v1/exception_list.hpp
new file mode 100644
index 00000000000..e4d3354f1c1
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/experimental/parallel/v1/exception_list.hpp
@@ -0,0 +1,70 @@
+#ifndef BOOST_THREAD_EXPERIMENTAL_PARALLEL_V1_EXCEPTION_LIST_HPP
+#define BOOST_THREAD_EXPERIMENTAL_PARALLEL_V1_EXCEPTION_LIST_HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2014. Distributed under the 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 http://www.boost.org/libs/thread for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/experimental/parallel/v1/inline_namespace.hpp>
+
+#include <boost/exception_ptr.hpp>
+#include <exception>
+#include <list>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+namespace experimental
+{
+namespace parallel
+{
+BOOST_THREAD_INLINE_NAMESPACE(v1)
+{
+
+ class BOOST_SYMBOL_VISIBLE exception_list: public std::exception
+ {
+ typedef std::list<exception_ptr> exception_ptr_list;
+ exception_ptr_list list_;
+ public:
+ typedef exception_ptr_list::const_iterator const_iterator;
+
+ ~exception_list() BOOST_NOEXCEPT_OR_NOTHROW {}
+
+ void add(exception_ptr const& e)
+ {
+ list_.push_back(e);
+ }
+ size_t size() const BOOST_NOEXCEPT
+ {
+ return list_.size();
+ }
+ const_iterator begin() const BOOST_NOEXCEPT
+ {
+ return list_.begin();
+ }
+ const_iterator end() const BOOST_NOEXCEPT
+ {
+ return list_.end();
+ }
+ const char* what() const BOOST_NOEXCEPT_OR_NOTHROW
+ {
+ return "exception_list";
+ }
+
+ };
+}
+
+} // parallel
+} // experimental
+} // boost
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/experimental/parallel/v1/inline_namespace.hpp b/src/third_party/boost-1.60.0/boost/thread/experimental/parallel/v1/inline_namespace.hpp
new file mode 100644
index 00000000000..a607e53c468
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/experimental/parallel/v1/inline_namespace.hpp
@@ -0,0 +1,28 @@
+#ifndef BOOST_THREAD_EXPERIMENTAL_PARALLEL_V1_INLINE_NAMESPACE_HPP
+#define BOOST_THREAD_EXPERIMENTAL_PARALLEL_V1_INLINE_NAMESPACE_HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2014. Distributed under the 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 http://www.boost.org/libs/thread for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/thread/experimental/config/inline_namespace.hpp>
+namespace boost {
+namespace experimental {
+namespace parallel {
+
+ BOOST_THREAD_INLINE_NAMESPACE(v1) {}
+
+#if defined(BOOST_NO_CXX11_INLINE_NAMESPACES)
+ using namespace v1;
+#endif
+
+}
+}
+}
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/experimental/parallel/v2/inline_namespace.hpp b/src/third_party/boost-1.60.0/boost/thread/experimental/parallel/v2/inline_namespace.hpp
new file mode 100644
index 00000000000..52d8e2904e8
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/experimental/parallel/v2/inline_namespace.hpp
@@ -0,0 +1,29 @@
+#ifndef BOOST_THREAD_EXPERIMENTAL_PARALLEL_V2_INLINE_NAMESPACE_HPP
+#define BOOST_THREAD_EXPERIMENTAL_PARALLEL_V2_INLINE_NAMESPACE_HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2014. Distributed under the 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 http://www.boost.org/libs/thread for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/thread/experimental/config/inline_namespace.hpp>
+
+namespace boost {
+namespace experimental {
+namespace parallel {
+
+ BOOST_THREAD_INLINE_NAMESPACE(v2) {}
+
+#if defined(BOOST_NO_CXX11_INLINE_NAMESPACES)
+ using namespace v2;
+#endif
+
+}
+}
+}
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/experimental/parallel/v2/task_region.hpp b/src/third_party/boost-1.60.0/boost/thread/experimental/parallel/v2/task_region.hpp
new file mode 100755
index 00000000000..e4a5833115f
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/experimental/parallel/v2/task_region.hpp
@@ -0,0 +1,316 @@
+#ifndef BOOST_THREAD_EXPERIMENTAL_PARALLEL_V2_TASK_REGION_HPP
+#define BOOST_THREAD_EXPERIMENTAL_PARALLEL_V2_TASK_REGION_HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2014-2015. Distributed under the 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 http://www.boost.org/libs/thread for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <boost/thread/detail/config.hpp>
+
+#include <boost/thread/future.hpp>
+#if defined BOOST_THREAD_PROVIDES_EXECUTORS
+#include <boost/thread/executors/basic_thread_pool.hpp>
+#endif
+#include <boost/thread/experimental/exception_list.hpp>
+#include <boost/thread/experimental/parallel/v2/inline_namespace.hpp>
+#include <boost/thread/detail/move.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+#define BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED
+
+namespace boost
+{
+namespace experimental
+{
+namespace parallel
+{
+BOOST_THREAD_INLINE_NAMESPACE(v2)
+{
+ class BOOST_SYMBOL_VISIBLE task_canceled_exception: public std::exception
+ {
+ public:
+ //task_canceled_exception() BOOST_NOEXCEPT {}
+ //task_canceled_exception(const task_canceled_exception&) BOOST_NOEXCEPT {}
+ //task_canceled_exception& operator=(const task_canceled_exception&) BOOST_NOEXCEPT {}
+ virtual const char* what() const BOOST_NOEXCEPT_OR_NOTHROW
+ { return "task_canceled_exception";}
+ };
+
+ template <class Executor>
+ class task_region_handle_gen;
+
+ namespace detail
+ {
+ void handle_task_region_exceptions(exception_list& errors)
+ {
+ try {
+ throw;
+ }
+#if defined BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED
+ catch (task_canceled_exception&)
+ {
+ }
+#endif
+ catch (exception_list const& el)
+ {
+ for (exception_list::const_iterator it = el.begin(); it != el.end(); ++it)
+ {
+ boost::exception_ptr const& e = *it;
+ try {
+ rethrow_exception(e);
+ }
+ catch (...)
+ {
+ handle_task_region_exceptions(errors);
+ }
+ }
+ }
+ catch (...)
+ {
+ errors.add(boost::current_exception());
+ }
+ }
+
+#if defined BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED
+ template <class TRH, class F>
+ struct wrapped
+ {
+ TRH& tr;
+ F f;
+ wrapped(TRH& tr, BOOST_THREAD_RV_REF(F) f) : tr(tr), f(move(f))
+ {}
+ void operator()()
+ {
+ try
+ {
+ f();
+ }
+ catch (...)
+ {
+ lock_guard<mutex> lk(tr.mtx);
+ tr.canceled = true;
+ throw;
+ }
+ }
+ };
+#endif
+ }
+
+ template <class Executor>
+ class task_region_handle_gen
+ {
+ private:
+ // Private members and friends
+#if defined BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED
+ template <class TRH, class F>
+ friend struct detail::wrapped;
+#endif
+ template <typename F>
+ friend void task_region(BOOST_THREAD_FWD_REF(F) f);
+ template<typename F>
+ friend void task_region_final(BOOST_THREAD_FWD_REF(F) f);
+ template <class Ex, typename F>
+ friend void task_region(Ex&, BOOST_THREAD_FWD_REF(F) f);
+ template<class Ex, typename F>
+ friend void task_region_final(Ex&, BOOST_THREAD_FWD_REF(F) f);
+
+ void wait_all()
+ {
+ wait_for_all(group.begin(), group.end());
+
+ for (group_type::iterator it = group.begin(); it != group.end(); ++it)
+ {
+ future<void>& f = *it;
+ if (f.has_exception())
+ {
+ try
+ {
+ boost::rethrow_exception(f.get_exception_ptr());
+ }
+ catch (...)
+ {
+ detail::handle_task_region_exceptions(exs);
+ }
+ }
+ }
+ if (exs.size() != 0)
+ {
+ boost::throw_exception(exs);
+ }
+ }
+protected:
+#if ! defined BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED && ! defined BOOST_THREAD_PROVIDES_EXECUTORS
+ task_region_handle_gen()
+ {}
+#endif
+
+#if defined BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED && defined BOOST_THREAD_PROVIDES_EXECUTORS
+ task_region_handle_gen()
+ : canceled(false)
+ , ex(0)
+ {}
+ task_region_handle_gen(Executor& ex)
+ : canceled(false)
+ , ex(&ex)
+ {}
+
+#endif
+
+#if ! defined BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED && defined BOOST_THREAD_PROVIDES_EXECUTORS
+ task_region_handle_gen()
+ : ex(0)
+ {}
+ task_region_handle_gen(Executor& ex)
+ : ex(&ex)
+ {}
+#endif
+
+#if defined BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED && ! defined BOOST_THREAD_PROVIDES_EXECUTORS
+ task_region_handle_gen()
+ : canceled(false)
+ {
+ }
+#endif
+
+ ~task_region_handle_gen()
+ {
+ //wait_all();
+ }
+
+#if defined BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED
+ mutable mutex mtx;
+ bool canceled;
+#endif
+#if defined BOOST_THREAD_PROVIDES_EXECUTORS
+ Executor* ex;
+#endif
+ exception_list exs;
+ typedef csbl::vector<future<void> > group_type;
+ group_type group;
+
+ public:
+ BOOST_DELETED_FUNCTION(task_region_handle_gen(const task_region_handle_gen&))
+ BOOST_DELETED_FUNCTION(task_region_handle_gen& operator=(const task_region_handle_gen&))
+ BOOST_DELETED_FUNCTION(task_region_handle_gen* operator&() const)
+
+ public:
+ template<typename F>
+ void run(BOOST_THREAD_FWD_REF(F) f)
+ {
+#if defined BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED
+ {
+ lock_guard<mutex> lk(mtx);
+ if (canceled) {
+ boost::throw_exception(task_canceled_exception());
+ }
+ }
+#if defined BOOST_THREAD_PROVIDES_EXECUTORS
+ group.push_back(async(*ex, detail::wrapped<task_region_handle_gen<Executor>, F>(*this, forward<F>(f))));
+#else
+ group.push_back(async(detail::wrapped<task_region_handle_gen<Executor>, F>(*this, forward<F>(f))));
+#endif
+#else
+#if defined BOOST_THREAD_PROVIDES_EXECUTORS
+ group.push_back(async(*ex, forward<F>(f)));
+#else
+ group.push_back(async(forward<F>(f)));
+#endif
+#endif
+ }
+
+ void wait()
+ {
+#if defined BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED
+ {
+ lock_guard<mutex> lk(mtx);
+ if (canceled) {
+ boost::throw_exception(task_canceled_exception());
+ }
+ }
+#endif
+ wait_all();
+ }
+ };
+#if defined BOOST_THREAD_PROVIDES_EXECUTORS
+ typedef basic_thread_pool default_executor;
+#else
+ typedef int default_executor;
+#endif
+ class task_region_handle :
+ public task_region_handle_gen<default_executor>
+ {
+ default_executor tp;
+ template <typename F>
+ friend void task_region(BOOST_THREAD_FWD_REF(F) f);
+ template<typename F>
+ friend void task_region_final(BOOST_THREAD_FWD_REF(F) f);
+
+ protected:
+ task_region_handle() : task_region_handle_gen<default_executor>()
+ {
+#if defined BOOST_THREAD_PROVIDES_EXECUTORS
+ ex = &tp;
+#endif
+ }
+ BOOST_DELETED_FUNCTION(task_region_handle(const task_region_handle&))
+ BOOST_DELETED_FUNCTION(task_region_handle& operator=(const task_region_handle&))
+ BOOST_DELETED_FUNCTION(task_region_handle* operator&() const)
+
+ };
+
+ template <typename Executor, typename F>
+ void task_region_final(Executor& ex, BOOST_THREAD_FWD_REF(F) f)
+ {
+ task_region_handle_gen<Executor> tr(ex);
+ try
+ {
+ f(tr);
+ }
+ catch (...)
+ {
+ detail::handle_task_region_exceptions(tr.exs);
+ }
+ tr.wait_all();
+ }
+
+ template <typename Executor, typename F>
+ void task_region(Executor& ex, BOOST_THREAD_FWD_REF(F) f)
+ {
+ task_region_final(ex, forward<F>(f));
+ }
+
+ template <typename F>
+ void task_region_final(BOOST_THREAD_FWD_REF(F) f)
+ {
+ task_region_handle tr;
+ try
+ {
+ f(tr);
+ }
+ catch (...)
+ {
+ detail::handle_task_region_exceptions(tr.exs);
+ }
+ tr.wait_all();
+ }
+
+ template <typename F>
+ void task_region(BOOST_THREAD_FWD_REF(F) f)
+ {
+ task_region_final(forward<F>(f));
+ }
+
+} // v2
+} // parallel
+} // experimental
+} // boost
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/experimental/task_region.hpp b/src/third_party/boost-1.60.0/boost/thread/experimental/task_region.hpp
new file mode 100644
index 00000000000..9b60d8b19ee
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/experimental/task_region.hpp
@@ -0,0 +1,16 @@
+#ifndef BOOST_THREAD_EXPERIMENTAL_TASK_REGION_HPP
+#define BOOST_THREAD_EXPERIMENTAL_TASK_REGION_HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2014. Distributed under the 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 http://www.boost.org/libs/thread for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/thread/experimental/parallel/v2/task_region.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/externally_locked.hpp b/src/third_party/boost-1.60.0/boost/thread/externally_locked.hpp
new file mode 100644
index 00000000000..0d4baaa512d
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/externally_locked.hpp
@@ -0,0 +1,351 @@
+// (C) Copyright 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)
+
+
+#ifndef BOOST_THREAD_EXTERNALLY_LOCKED_HPP
+#define BOOST_THREAD_EXTERNALLY_LOCKED_HPP
+
+#include <boost/thread/detail/config.hpp>
+
+#include <boost/thread/exceptions.hpp>
+#include <boost/thread/lock_concepts.hpp>
+#include <boost/thread/lock_traits.hpp>
+#include <boost/thread/lockable_concepts.hpp>
+#include <boost/thread/strict_lock.hpp>
+
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/core/swap.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+
+ /**
+ * externally_locked cloaks an object of type T, and actually provides full
+ * access to that object through the get and set member functions, provided you
+ * pass a reference to a strict lock object
+ */
+
+ //[externally_locked
+ template <typename T, typename MutexType = boost::mutex>
+ class externally_locked;
+ template <typename T, typename MutexType>
+ class externally_locked
+ {
+ //BOOST_CONCEPT_ASSERT(( CopyConstructible<T> ));
+ BOOST_CONCEPT_ASSERT(( BasicLockable<MutexType> ));
+
+ public:
+ typedef MutexType mutex_type;
+
+ BOOST_THREAD_COPYABLE_AND_MOVABLE( externally_locked )
+ /**
+ * Requires: T is a model of CopyConstructible.
+ * Effects: Constructs an externally locked object copying the cloaked type.
+ */
+ externally_locked(mutex_type& mtx, const T& obj) :
+ obj_(obj), mtx_(&mtx)
+ {
+ }
+
+ /**
+ * Requires: T is a model of Movable.
+ * Effects: Constructs an externally locked object by moving the cloaked type.
+ */
+ externally_locked(mutex_type& mtx, BOOST_THREAD_RV_REF(T) obj) :
+ obj_(move(obj)), mtx_(&mtx)
+ {
+ }
+
+ /**
+ * Requires: T is a model of DefaultConstructible.
+ * Effects: Constructs an externally locked object initializing the cloaked type with the default constructor.
+ */
+ externally_locked(mutex_type& mtx) // BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(T()))
+ : obj_(), mtx_(&mtx)
+ {
+ }
+
+ /**
+ * Copy constructor
+ */
+ externally_locked(externally_locked const& rhs) //BOOST_NOEXCEPT
+ : obj_(rhs.obj_), mtx_(rhs.mtx_)
+ {
+ }
+ /**
+ * Move constructor
+ */
+ externally_locked(BOOST_THREAD_RV_REF(externally_locked) rhs) //BOOST_NOEXCEPT
+ : obj_(move(rhs.obj_)), mtx_(rhs.mtx_)
+ {
+ }
+
+ /// assignment
+ externally_locked& operator=(externally_locked const& rhs) //BOOST_NOEXCEPT
+ {
+ obj_=rhs.obj_;
+ mtx_=rhs.mtx_;
+ return *this;
+ }
+
+ /// move assignment
+ externally_locked& operator=(BOOST_THREAD_RV_REF(externally_locked) rhs) // BOOST_NOEXCEPT
+ {
+ obj_=move(BOOST_THREAD_RV(rhs).obj_);
+ mtx_=rhs.mtx_;
+ return *this;
+ }
+
+ void swap(externally_locked& rhs) //BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR)
+ {
+ swap(obj_, rhs.obj_);
+ swap(mtx_, rhs.mtx_);
+ }
+
+ /**
+ * Requires: The lk parameter must be locking the associated mtx.
+ *
+ * Returns: The address of the cloaked object..
+ *
+ * Throws: lock_error if BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is not defined and the lk parameter doesn't satisfy the preconditions
+ */
+ T& get(strict_lock<mutex_type>& lk)
+ {
+ BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
+ return obj_;
+ }
+
+ const T& get(strict_lock<mutex_type>& lk) const
+ {
+ BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
+ return obj_;
+ }
+
+ template <class Lock>
+ T& get(nested_strict_lock<Lock>& lk)
+ {
+ BOOST_STATIC_ASSERT( (is_same<mutex_type, typename Lock::mutex_type>::value)); /*< that locks the same type >*/
+ BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
+ return obj_;
+ }
+
+ template <class Lock>
+ const T& get(nested_strict_lock<Lock>& lk) const
+ {
+ BOOST_STATIC_ASSERT( (is_same<mutex_type, typename Lock::mutex_type>::value)); /*< that locks the same type >*/
+ BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
+ return obj_;
+ }
+
+ /**
+ * Requires: The lk parameter must be locking the associated mtx.
+ * Returns: The address of the cloaked object..
+ *
+ * Throws: lock_error if BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is not defined and the lk parameter doesn't satisfy the preconditions
+ */
+ template <class Lock>
+ T& get(Lock& lk)
+ {
+ BOOST_CONCEPT_ASSERT(( StrictLock<Lock> ));
+ BOOST_STATIC_ASSERT( (is_strict_lock<Lock>::value)); /*< lk is a strict lock "sur parolle" >*/
+ BOOST_STATIC_ASSERT( (is_same<mutex_type, typename Lock::mutex_type>::value)); /*< that locks the same type >*/
+
+ BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
+
+ return obj_;
+ }
+
+ mutex_type* mutex() const BOOST_NOEXCEPT
+ {
+ return mtx_;
+ }
+
+ // modifiers
+
+ void lock()
+ {
+ mtx_->lock();
+ }
+ void unlock()
+ {
+ mtx_->unlock();
+ }
+ bool try_lock()
+ {
+ return mtx_->try_lock();
+ }
+ // todo add time related functions
+
+ private:
+ T obj_;
+ mutex_type* mtx_;
+ };
+ //]
+
+ /**
+ * externally_locked<T&,M> specialization for T& that cloaks an reference to an object of type T, and actually
+ * provides full access to that object through the get and set member functions, provided you
+ * pass a reference to a strict lock object.
+ */
+
+ //[externally_locked_ref
+ template <typename T, typename MutexType>
+ class externally_locked<T&, MutexType>
+ {
+ //BOOST_CONCEPT_ASSERT(( CopyConstructible<T> ));
+ BOOST_CONCEPT_ASSERT(( BasicLockable<MutexType> ));
+
+ public:
+ typedef MutexType mutex_type;
+
+ BOOST_THREAD_COPYABLE_AND_MOVABLE( externally_locked )
+
+ /**
+ * Effects: Constructs an externally locked object storing the cloaked reference object.
+ */
+ externally_locked(T& obj, mutex_type& mtx) BOOST_NOEXCEPT :
+ obj_(&obj), mtx_(&mtx)
+ {
+ }
+
+ /// copy constructor
+ externally_locked(externally_locked const& rhs) BOOST_NOEXCEPT :
+ obj_(rhs.obj_), mtx_(rhs.mtx_)
+ {
+ }
+
+ /// move constructor
+ externally_locked(BOOST_THREAD_RV_REF(externally_locked) rhs) BOOST_NOEXCEPT :
+ obj_(rhs.obj_), mtx_(rhs.mtx_)
+ {
+ }
+
+ /// assignment
+ externally_locked& operator=(externally_locked const& rhs) BOOST_NOEXCEPT
+ {
+ obj_=rhs.obj_;
+ mtx_=rhs.mtx_;
+ return *this;
+ }
+
+ /// move assignment
+ externally_locked& operator=(BOOST_THREAD_RV_REF(externally_locked) rhs) BOOST_NOEXCEPT
+ {
+ obj_=rhs.obj_;
+ mtx_=rhs.mtx_;
+ return *this;
+ }
+
+ void swap(externally_locked& rhs) BOOST_NOEXCEPT
+ {
+ swap(obj_, rhs.obj_);
+ swap(mtx_, rhs.mtx_);
+ }
+ /**
+ * Requires: The lk parameter must be locking the associated mtx.
+ *
+ * Returns: The address of the cloaked object..
+ *
+ * Throws: lock_error if BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is not defined and the lk parameter doesn't satisfy the preconditions
+ */
+ T& get(strict_lock<mutex_type> const& lk)
+ {
+ BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
+ return *obj_;
+ }
+
+ const T& get(strict_lock<mutex_type> const& lk) const
+ {
+ BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
+ return *obj_;
+ }
+
+ template <class Lock>
+ T& get(nested_strict_lock<Lock> const& lk)
+ {
+ BOOST_STATIC_ASSERT( (is_same<mutex_type, typename Lock::mutex_type>::value)); /*< that locks the same type >*/
+ BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
+ return *obj_;
+ }
+
+ template <class Lock>
+ const T& get(nested_strict_lock<Lock> const& lk) const
+ {
+ BOOST_STATIC_ASSERT( (is_same<mutex_type, typename Lock::mutex_type>::value)); /*< that locks the same type >*/
+ BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
+ return *obj_;
+ }
+
+ /**
+ * Requires: The lk parameter must be locking the associated mtx.
+ * Returns: The address of the cloaked object..
+ *
+ * Throws: lock_error if BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is not defined and the lk parameter doesn't satisfy the preconditions
+ */
+ template <class Lock>
+ T& get(Lock const& lk)
+ {
+ BOOST_CONCEPT_ASSERT(( StrictLock<Lock> ));
+ BOOST_STATIC_ASSERT( (is_strict_lock<Lock>::value)); /*< lk is a strict lock "sur parolle" >*/
+ BOOST_STATIC_ASSERT( (is_same<mutex_type, typename Lock::mutex_type>::value)); /*< that locks the same type >*/
+ BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
+ return *obj_;
+ }
+
+ /**
+ * Requires: The lk parameter must be locking the associated mtx.
+ * Returns: The address of the cloaked object..
+ *
+ * Throws: lock_error if BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is not defined and the lk parameter doesn't satisfy the preconditions
+ */
+ template <class Lock>
+ T const& get(Lock const& lk) const
+ {
+ BOOST_CONCEPT_ASSERT(( StrictLock<Lock> ));
+ BOOST_STATIC_ASSERT( (is_strict_lock<Lock>::value)); /*< lk is a strict lock "sur parolle" >*/
+ BOOST_STATIC_ASSERT( (is_same<mutex_type, typename Lock::mutex_type>::value)); /*< that locks the same type >*/
+ BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
+ return *obj_;
+ }
+ mutex_type* mutex() const BOOST_NOEXCEPT
+ {
+ return mtx_;
+ }
+
+ void lock()
+ {
+ mtx_->lock();
+ }
+ void unlock()
+ {
+ mtx_->unlock();
+ }
+ bool try_lock()
+ {
+ return mtx_->try_lock();
+ }
+ // todo add time related functions
+
+ protected:
+ T* obj_;
+ mutex_type* mtx_;
+ };
+ //]
+
+ template <typename T, typename MutexType>
+ void swap(externally_locked<T, MutexType> & lhs, externally_locked<T, MutexType> & rhs) // BOOST_NOEXCEPT
+ {
+ lhs.swap(rhs);
+ }
+
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/externally_locked_stream.hpp b/src/third_party/boost-1.60.0/boost/thread/externally_locked_stream.hpp
new file mode 100644
index 00000000000..aa9aeff79d9
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/externally_locked_stream.hpp
@@ -0,0 +1,170 @@
+// (C) Copyright 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)
+
+
+#ifndef BOOST_THREAD_EXTERNALLY_LOCKED_STREAM_HPP
+#define BOOST_THREAD_EXTERNALLY_LOCKED_STREAM_HPP
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/detail/delete.hpp>
+
+#include <boost/thread/externally_locked.hpp>
+#include <boost/thread/lock_traits.hpp>
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/thread/strict_lock.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+
+ template <typename Stream, typename RecursiveMutex=recursive_mutex>
+ class externally_locked_stream;
+
+ template <class Stream, typename RecursiveMutex=recursive_mutex>
+ class stream_guard
+ {
+
+ friend class externally_locked_stream<Stream, RecursiveMutex> ;
+ public:
+ typedef typename externally_locked_stream<Stream, RecursiveMutex>::mutex_type mutex_type;
+
+ BOOST_THREAD_MOVABLE_ONLY( stream_guard)
+
+ stream_guard(externally_locked_stream<Stream, RecursiveMutex>& mtx) :
+ mtx_(&mtx)
+ {
+ mtx.lock();
+ }
+
+ stream_guard(externally_locked_stream<Stream, RecursiveMutex>& mtx, adopt_lock_t) :
+ mtx_(&mtx)
+ {
+ }
+
+ stream_guard(BOOST_THREAD_RV_REF(stream_guard) rhs) BOOST_NOEXCEPT
+ : mtx_(rhs.mtx_)
+ {
+ rhs.mtx_= 0;
+ }
+
+ ~stream_guard()
+ {
+ if (mtx_ != 0) mtx_->unlock();
+ }
+
+ bool owns_lock(const mutex_type * l) const BOOST_NOEXCEPT
+ {
+ return l == mtx_->mutex();
+ }
+
+ /**
+ * @Requires mtx_
+ */
+ Stream& get() const
+ {
+ BOOST_THREAD_ASSERT_PRECONDITION( mtx_, lock_error() );
+ return mtx_->get(*this);
+ }
+ Stream& bypass() const
+ {
+ return get();
+ }
+
+
+ private:
+ externally_locked_stream<Stream, RecursiveMutex>* mtx_;
+ };
+
+ template <typename Stream, typename RecursiveMutex>
+ struct is_strict_lock_sur_parole<stream_guard<Stream, RecursiveMutex> > : true_type
+ {
+ };
+
+ /**
+ * externally_locked_stream cloaks a reference to an stream of type Stream, and actually
+ * provides full access to that object through the get and set member functions, provided you
+ * pass a reference to a strict lock object.
+ */
+
+ //[externally_locked_stream
+ template <typename Stream, typename RecursiveMutex>
+ class externally_locked_stream: public externally_locked<Stream&, RecursiveMutex>
+ {
+ typedef externally_locked<Stream&, RecursiveMutex> base_type;
+ public:
+ BOOST_THREAD_NO_COPYABLE( externally_locked_stream)
+
+ /**
+ * Effects: Constructs an externally locked object storing the cloaked reference object.
+ */
+ externally_locked_stream(Stream& stream, RecursiveMutex& mtx) BOOST_NOEXCEPT :
+ base_type(stream, mtx)
+ {
+ }
+
+ stream_guard<Stream, RecursiveMutex> hold() BOOST_NOEXCEPT
+ {
+ return stream_guard<Stream, RecursiveMutex> (*this);
+ }
+ Stream& bypass() const
+ {
+ stream_guard<Stream, RecursiveMutex> lk(*this);
+ return get(lk);
+ }
+ };
+ //]
+
+ template <typename Stream, typename RecursiveMutex, typename T>
+ inline const stream_guard<Stream, RecursiveMutex>& operator<<(const stream_guard<Stream, RecursiveMutex>& lck, T arg)
+ {
+ lck.get() << arg;
+ return lck;
+ }
+
+ template <typename Stream, typename RecursiveMutex>
+ inline const stream_guard<Stream, RecursiveMutex>& operator<<(const stream_guard<Stream, RecursiveMutex>& lck, Stream& (*arg)(Stream&))
+ {
+ lck.get() << arg;
+ return lck;
+ }
+
+ template <typename Stream, typename RecursiveMutex, typename T>
+ inline const stream_guard<Stream, RecursiveMutex>& operator>>(const stream_guard<Stream, RecursiveMutex>& lck, T& arg)
+ {
+ lck.get() >> arg;
+ return lck;
+ }
+
+ template <typename Stream, typename RecursiveMutex, typename T>
+ inline stream_guard<Stream, RecursiveMutex> operator<<(externally_locked_stream<Stream, RecursiveMutex>& mtx, T arg)
+ {
+ stream_guard<Stream, RecursiveMutex> lk(mtx);
+ mtx.get(lk) << arg;
+ return boost::move(lk);
+ }
+
+ template <typename Stream, typename RecursiveMutex>
+ inline stream_guard<Stream, RecursiveMutex> operator<<(externally_locked_stream<Stream, RecursiveMutex>& mtx, Stream& (*arg)(Stream&))
+ {
+ stream_guard<Stream, RecursiveMutex> lk(mtx);
+ mtx.get(lk) << arg;
+ return boost::move(lk);
+ }
+
+ template <typename Stream, typename RecursiveMutex, typename T>
+ inline stream_guard<Stream, RecursiveMutex> operator>>(externally_locked_stream<Stream, RecursiveMutex>& mtx, T& arg)
+ {
+ stream_guard<Stream, RecursiveMutex> lk(mtx);
+ mtx.get(lk) >> arg;
+ return boost::move(lk);
+ }
+
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/future.hpp b/src/third_party/boost-1.60.0/boost/thread/future.hpp
new file mode 100644
index 00000000000..0ec484c2bf9
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/future.hpp
@@ -0,0 +1,5552 @@
+// (C) Copyright 2008-10 Anthony Williams
+// (C) Copyright 2011-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)
+
+#ifndef BOOST_THREAD_FUTURE_HPP
+#define BOOST_THREAD_FUTURE_HPP
+
+#include <boost/thread/detail/config.hpp>
+
+// boost::thread::future requires exception handling
+// due to boost::exception::exception_ptr dependency
+
+//#define BOOST_THREAD_CONTINUATION_SYNC
+#define BOOST_THREAD_FUTURE_BLOCKING
+
+#ifndef BOOST_NO_EXCEPTIONS
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/detail/invoker.hpp>
+#include <boost/thread/detail/invoke.hpp>
+#include <boost/thread/detail/is_convertible.hpp>
+#include <boost/thread/exceptional_ptr.hpp>
+#include <boost/thread/futures/future_error.hpp>
+#include <boost/thread/futures/future_error_code.hpp>
+#include <boost/thread/futures/future_status.hpp>
+#include <boost/thread/futures/is_future_type.hpp>
+#include <boost/thread/futures/launch.hpp>
+#include <boost/thread/futures/wait_for_all.hpp>
+#include <boost/thread/futures/wait_for_any.hpp>
+#include <boost/thread/lock_algorithms.hpp>
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread_only.hpp>
+#include <boost/thread/thread_time.hpp>
+#include <boost/thread/executor.hpp>
+#include <boost/thread/executors/generic_executor_ref.hpp>
+
+#if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
+#include <boost/optional.hpp>
+#else
+#include <boost/thread/csbl/memory/unique_ptr.hpp>
+#endif
+
+#include <boost/assert.hpp>
+#include <boost/bind.hpp>
+#ifdef BOOST_THREAD_USES_CHRONO
+#include <boost/chrono/system_clocks.hpp>
+#endif
+#include <boost/core/enable_if.hpp>
+#include <boost/core/ref.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <boost/exception_ptr.hpp>
+#include <boost/function.hpp>
+#include <boost/next_prior.hpp>
+#include <boost/scoped_array.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/smart_ptr/make_shared.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/type_traits/conditional.hpp>
+#include <boost/type_traits/decay.hpp>
+#include <boost/type_traits/is_copy_constructible.hpp>
+#include <boost/type_traits/is_fundamental.hpp>
+#include <boost/type_traits/is_void.hpp>
+#include <boost/utility/result_of.hpp>
+
+
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+#include <boost/thread/detail/memory.hpp>
+#include <boost/container/scoped_allocator.hpp>
+#if ! defined BOOST_NO_CXX11_ALLOCATOR
+#include <memory>
+#endif
+#endif
+
+#if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
+#include <boost/thread/csbl/tuple.hpp>
+#include <boost/thread/csbl/vector.hpp>
+#endif
+
+#include <algorithm>
+#include <list>
+#include <vector>
+#include <utility>
+
+#if defined BOOST_THREAD_PROVIDES_FUTURE
+#define BOOST_THREAD_FUTURE future
+#else
+#define BOOST_THREAD_FUTURE unique_future
+#endif
+
+namespace boost
+{
+ template <class T>
+ shared_ptr<T> static_shared_from_this(T* that)
+ {
+ return static_pointer_cast<T>(that->shared_from_this());
+ }
+ template <class T>
+ shared_ptr<T const> static_shared_from_this(T const* that)
+ {
+ return static_pointer_cast<T const>(that->shared_from_this());
+ }
+
+#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
+#else
+ namespace executors {
+ class executor;
+ }
+#endif
+ typedef shared_ptr<executor> executor_ptr_type;
+
+ namespace detail
+ {
+
+ struct relocker
+ {
+ boost::unique_lock<boost::mutex>& lock_;
+
+ relocker(boost::unique_lock<boost::mutex>& lk):
+ lock_(lk)
+ {
+ lock_.unlock();
+ }
+ ~relocker()
+ {
+ if (! lock_.owns_lock()) {
+ lock_.lock();
+ }
+ }
+ void lock() {
+ if (! lock_.owns_lock()) {
+ lock_.lock();
+ }
+ }
+ private:
+ relocker& operator=(relocker const&);
+ };
+
+ struct shared_state_base : enable_shared_from_this<shared_state_base>
+ {
+ typedef std::list<boost::condition_variable_any*> waiter_list;
+ typedef waiter_list::iterator notify_when_ready_handle;
+ // This type should be only included conditionally if interruptions are allowed, but is included to maintain the same layout.
+ typedef shared_ptr<shared_state_base> continuation_ptr_type;
+ typedef std::vector<continuation_ptr_type> continuations_type;
+
+ boost::exception_ptr exception;
+ bool done;
+ bool is_valid_;
+ bool is_deferred_;
+ bool is_constructed;
+ launch policy_;
+ mutable boost::mutex mutex;
+ boost::condition_variable waiters;
+ waiter_list external_waiters;
+ boost::function<void()> callback;
+ // This declaration should be only included conditionally, but is included to maintain the same layout.
+ continuations_type continuations;
+ executor_ptr_type ex;
+
+ // This declaration should be only included conditionally, but is included to maintain the same layout.
+ virtual void launch_continuation()
+ {
+ }
+
+ shared_state_base():
+ done(false),
+ is_valid_(true),
+ is_deferred_(false),
+ is_constructed(false),
+ policy_(launch::none),
+ continuations(),
+ ex()
+ {}
+
+ shared_state_base(exceptional_ptr const& ex):
+ exception(ex.ptr_),
+ done(true),
+ is_valid_(true),
+ is_deferred_(false),
+ is_constructed(false),
+ policy_(launch::none),
+ continuations(),
+ ex()
+ {}
+
+
+ virtual ~shared_state_base()
+ {
+ }
+ executor_ptr_type get_executor()
+ {
+ return ex;
+ }
+
+ void set_executor_policy(executor_ptr_type aex)
+ {
+ set_executor();
+ ex = aex;
+ }
+ void set_executor_policy(executor_ptr_type aex, boost::lock_guard<boost::mutex>&)
+ {
+ set_executor();
+ ex = aex;
+ }
+ void set_executor_policy(executor_ptr_type aex, boost::unique_lock<boost::mutex>&)
+ {
+ set_executor();
+ ex = aex;
+ }
+
+ bool valid(boost::unique_lock<boost::mutex>&) { return is_valid_; }
+ bool valid() {
+ boost::unique_lock<boost::mutex> lk(this->mutex);
+ return valid(lk);
+ }
+ void invalidate(boost::unique_lock<boost::mutex>&) { is_valid_ = false; }
+ void invalidate() {
+ boost::unique_lock<boost::mutex> lk(this->mutex);
+ invalidate(lk);
+ }
+ void validate(boost::unique_lock<boost::mutex>&) { is_valid_ = true; }
+ void validate() {
+ boost::unique_lock<boost::mutex> lk(this->mutex);
+ validate(lk);
+ }
+
+ void set_deferred()
+ {
+ is_deferred_ = true;
+ policy_ = launch::deferred;
+ }
+ void set_async()
+ {
+ is_deferred_ = false;
+ policy_ = launch::async;
+ }
+#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
+ void set_executor()
+ {
+ is_deferred_ = false;
+ policy_ = launch::executor;
+ }
+#else
+ void set_executor()
+ {
+ }
+#endif
+ notify_when_ready_handle notify_when_ready(boost::condition_variable_any& cv)
+ {
+ boost::unique_lock<boost::mutex> lock(this->mutex);
+ do_callback(lock);
+ return external_waiters.insert(external_waiters.end(),&cv);
+ }
+
+ void unnotify_when_ready(notify_when_ready_handle it)
+ {
+ boost::lock_guard<boost::mutex> lock(this->mutex);
+ external_waiters.erase(it);
+ }
+
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
+ void do_continuation(boost::unique_lock<boost::mutex>& lock)
+ {
+ if (! continuations.empty()) {
+ continuations_type the_continuations = continuations;
+ continuations.clear();
+ relocker rlk(lock);
+ for (continuations_type::iterator it = the_continuations.begin(); it != the_continuations.end(); ++it) {
+ (*it)->launch_continuation();
+ }
+ }
+ }
+#else
+ void do_continuation(boost::unique_lock<boost::mutex>&)
+ {
+ }
+#endif
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
+ virtual void set_continuation_ptr(continuation_ptr_type continuation, boost::unique_lock<boost::mutex>& lock)
+ {
+ continuations.push_back(continuation);
+ if (done) {
+ do_continuation(lock);
+ }
+ }
+#endif
+ void mark_finished_internal(boost::unique_lock<boost::mutex>& lock)
+ {
+ done=true;
+ waiters.notify_all();
+ for(waiter_list::const_iterator it=external_waiters.begin(),
+ end=external_waiters.end();it!=end;++it)
+ {
+ (*it)->notify_all();
+ }
+ do_continuation(lock);
+ }
+ void make_ready()
+ {
+ boost::unique_lock<boost::mutex> lock(this->mutex);
+ mark_finished_internal(lock);
+ }
+
+ void do_callback(boost::unique_lock<boost::mutex>& lock)
+ {
+ if(callback && !done)
+ {
+ boost::function<void()> local_callback=callback;
+ relocker relock(lock);
+ local_callback();
+ }
+ }
+
+ virtual bool run_if_is_deferred()
+ {
+ boost::unique_lock<boost::mutex> lk(this->mutex);
+ if (is_deferred_)
+ {
+ is_deferred_=false;
+ execute(lk);
+ return true;
+ }
+ else
+ return false;
+ }
+ virtual bool run_if_is_deferred_or_ready()
+ {
+ boost::unique_lock<boost::mutex> lk(this->mutex);
+ if (is_deferred_)
+ {
+ is_deferred_=false;
+ execute(lk);
+
+ return true;
+ }
+ else
+ return done;
+ }
+ void wait_internal(boost::unique_lock<boost::mutex> &lk, bool rethrow=true)
+ {
+ do_callback(lk);
+ if (is_deferred_)
+ {
+ is_deferred_=false;
+ execute(lk);
+ }
+ while(!done)
+ {
+ waiters.wait(lk);
+ }
+ if(rethrow && exception)
+ {
+ boost::rethrow_exception(exception);
+ }
+ }
+
+ virtual void wait(boost::unique_lock<boost::mutex>& lock, bool rethrow=true)
+ {
+ wait_internal(lock, rethrow);
+ }
+
+ void wait(bool rethrow=true)
+ {
+ boost::unique_lock<boost::mutex> lock(this->mutex);
+ wait(lock, rethrow);
+ }
+
+#if defined BOOST_THREAD_USES_DATETIME
+ bool timed_wait_until(boost::system_time const& target_time)
+ {
+ boost::unique_lock<boost::mutex> lock(this->mutex);
+ if (is_deferred_)
+ return false;
+
+ do_callback(lock);
+ while(!done)
+ {
+ bool const success=waiters.timed_wait(lock,target_time);
+ if(!success && !done)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+#endif
+#ifdef BOOST_THREAD_USES_CHRONO
+
+ template <class Clock, class Duration>
+ future_status
+ wait_until(const chrono::time_point<Clock, Duration>& abs_time)
+ {
+ boost::unique_lock<boost::mutex> lock(this->mutex);
+ if (is_deferred_)
+ return future_status::deferred;
+ do_callback(lock);
+ while(!done)
+ {
+ cv_status const st=waiters.wait_until(lock,abs_time);
+ if(st==cv_status::timeout && !done)
+ {
+ return future_status::timeout;
+ }
+ }
+ return future_status::ready;
+ }
+#endif
+ void mark_exceptional_finish_internal(boost::exception_ptr const& e, boost::unique_lock<boost::mutex>& lock)
+ {
+ exception=e;
+ mark_finished_internal(lock);
+ }
+
+ void mark_exceptional_finish()
+ {
+ boost::unique_lock<boost::mutex> lock(this->mutex);
+ mark_exceptional_finish_internal(boost::current_exception(), lock);
+ }
+
+ void set_exception_at_thread_exit(exception_ptr e)
+ {
+ unique_lock<boost::mutex> lk(this->mutex);
+ if (has_value(lk))
+ {
+ throw_exception(promise_already_satisfied());
+ }
+ exception=e;
+ this->is_constructed = true;
+ detail::make_ready_at_thread_exit(shared_from_this());
+ }
+
+ bool has_value() const
+ {
+ boost::lock_guard<boost::mutex> lock(this->mutex);
+ return done && ! exception;
+ }
+
+ bool has_value(unique_lock<boost::mutex>& ) const
+ {
+ return done && ! exception;
+ }
+
+ bool has_exception() const
+ {
+ boost::lock_guard<boost::mutex> lock(this->mutex);
+ return done && exception;
+ }
+
+ launch launch_policy(boost::unique_lock<boost::mutex>&) const
+ {
+ return policy_;
+ }
+
+ future_state::state get_state(boost::unique_lock<boost::mutex>&) const
+ {
+ if(!done)
+ {
+ return future_state::waiting;
+ }
+ else
+ {
+ return future_state::ready;
+ }
+ }
+ future_state::state get_state() const
+ {
+ boost::lock_guard<boost::mutex> guard(this->mutex);
+ if(!done)
+ {
+ return future_state::waiting;
+ }
+ else
+ {
+ return future_state::ready;
+ }
+ }
+
+ exception_ptr get_exception_ptr()
+ {
+ boost::unique_lock<boost::mutex> lock(this->mutex);
+ wait_internal(lock, false);
+ return exception;
+ }
+
+ template<typename F,typename U>
+ void set_wait_callback(F f,U* u)
+ {
+ boost::lock_guard<boost::mutex> lock(this->mutex);
+ callback=boost::bind(f,boost::ref(*u));
+ }
+
+ virtual void execute(boost::unique_lock<boost::mutex>&) {}
+
+ private:
+ shared_state_base(shared_state_base const&);
+ shared_state_base& operator=(shared_state_base const&);
+ };
+
+ // Used to create stand-alone futures
+ template<typename T>
+ struct shared_state:
+ detail::shared_state_base
+ {
+#if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
+ typedef boost::optional<T> storage_type;
+#else
+ typedef boost::csbl::unique_ptr<T> storage_type;
+#endif
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ typedef T const& source_reference_type;
+ typedef BOOST_THREAD_RV_REF(T) rvalue_source_type;
+ typedef T move_dest_type;
+#elif defined BOOST_THREAD_USES_MOVE
+ typedef typename conditional<boost::is_fundamental<T>::value,T,T const&>::type source_reference_type;
+ typedef BOOST_THREAD_RV_REF(T) rvalue_source_type;
+ typedef T move_dest_type;
+#else
+ typedef T& source_reference_type;
+ typedef typename conditional<boost::thread_detail::is_convertible<T&,BOOST_THREAD_RV_REF(T) >::value, BOOST_THREAD_RV_REF(T),T const&>::type rvalue_source_type;
+ typedef typename conditional<boost::thread_detail::is_convertible<T&,BOOST_THREAD_RV_REF(T) >::value, BOOST_THREAD_RV_REF(T),T>::type move_dest_type;
+#endif
+
+ typedef const T& shared_future_get_result_type;
+
+ storage_type result;
+
+ shared_state():
+ result()
+ {}
+ shared_state(exceptional_ptr const& ex):
+ detail::shared_state_base(ex), result()
+ {}
+
+
+ ~shared_state()
+ {
+ }
+
+ void mark_finished_with_result_internal(source_reference_type result_, boost::unique_lock<boost::mutex>& lock)
+ {
+#if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
+ result = result_;
+#else
+ result.reset(new T(result_));
+#endif
+ this->mark_finished_internal(lock);
+ }
+
+ void mark_finished_with_result_internal(rvalue_source_type result_, boost::unique_lock<boost::mutex>& lock)
+ {
+#if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
+ result = boost::move(result_);
+#elif ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ result.reset(new T(boost::move(result_)));
+#else
+ result.reset(new T(static_cast<rvalue_source_type>(result_)));
+#endif
+ this->mark_finished_internal(lock);
+ }
+
+
+#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template <class ...Args>
+ void mark_finished_with_result_internal(boost::unique_lock<boost::mutex>& lock, BOOST_THREAD_FWD_REF(Args)... args)
+ {
+#if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
+ result.emplace(boost::forward<Args>(args)...);
+#else
+ result.reset(new T(boost::forward<Args>(args)...));
+#endif
+ this->mark_finished_internal(lock);
+ }
+#endif
+
+ void mark_finished_with_result(source_reference_type result_)
+ {
+ boost::unique_lock<boost::mutex> lock(this->mutex);
+ this->mark_finished_with_result_internal(result_, lock);
+ }
+
+ void mark_finished_with_result(rvalue_source_type result_)
+ {
+ boost::unique_lock<boost::mutex> lock(this->mutex);
+
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ mark_finished_with_result_internal(boost::move(result_), lock);
+#else
+ mark_finished_with_result_internal(static_cast<rvalue_source_type>(result_), lock);
+#endif
+ }
+
+ storage_type& get_storage(boost::unique_lock<boost::mutex>& lk)
+ {
+ wait_internal(lk);
+ return result;
+ }
+ virtual move_dest_type get(boost::unique_lock<boost::mutex>& lk)
+ {
+ return boost::move(*get_storage(lk));
+ }
+ move_dest_type get()
+ {
+ boost::unique_lock<boost::mutex> lk(this->mutex);
+ return this->get(lk);
+ }
+
+ virtual shared_future_get_result_type get_sh(boost::unique_lock<boost::mutex>& lk)
+ {
+ return *get_storage(lk);
+ }
+ shared_future_get_result_type get_sh()
+ {
+ boost::unique_lock<boost::mutex> lk(this->mutex);
+ return this->get_sh(lk);
+ }
+
+ void set_value_at_thread_exit(source_reference_type result_)
+ {
+ unique_lock<boost::mutex> lk(this->mutex);
+ if (this->has_value(lk))
+ {
+ throw_exception(promise_already_satisfied());
+ }
+#if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
+ result = result_;
+#else
+ result.reset(new T(result_));
+#endif
+
+ this->is_constructed = true;
+ detail::make_ready_at_thread_exit(shared_from_this());
+ }
+ void set_value_at_thread_exit(rvalue_source_type result_)
+ {
+ unique_lock<boost::mutex> lk(this->mutex);
+ if (this->has_value(lk))
+ throw_exception(promise_already_satisfied());
+
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+#if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
+ result = boost::move(result_);
+#else
+ result.reset(new T(boost::move(result_)));
+#endif
+#else
+#if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
+ result = boost::move(result_);
+#else
+ result.reset(new T(static_cast<rvalue_source_type>(result_)));
+#endif
+#endif
+ this->is_constructed = true;
+ detail::make_ready_at_thread_exit(shared_from_this());
+ }
+
+ private:
+ shared_state(shared_state const&);
+ shared_state& operator=(shared_state const&);
+ };
+
+ template<typename T>
+ struct shared_state<T&>:
+ detail::shared_state_base
+ {
+ typedef T* storage_type;
+ typedef T& source_reference_type;
+ typedef T& move_dest_type;
+ typedef T& shared_future_get_result_type;
+
+ T* result;
+
+ shared_state():
+ result(0)
+ {}
+
+ shared_state(exceptional_ptr const& ex):
+ detail::shared_state_base(ex), result(0)
+ {}
+
+ ~shared_state()
+ {
+ }
+
+ void mark_finished_with_result_internal(source_reference_type result_, boost::unique_lock<boost::mutex>& lock)
+ {
+ result= &result_;
+ mark_finished_internal(lock);
+ }
+
+ void mark_finished_with_result(source_reference_type result_)
+ {
+ boost::unique_lock<boost::mutex> lock(this->mutex);
+ mark_finished_with_result_internal(result_, lock);
+ }
+
+ virtual T& get(boost::unique_lock<boost::mutex>& lock)
+ {
+ wait_internal(lock);
+ return *result;
+ }
+ T& get()
+ {
+ boost::unique_lock<boost::mutex> lk(this->mutex);
+ return get(lk);
+ }
+
+ virtual T& get_sh(boost::unique_lock<boost::mutex>& lock)
+ {
+ wait_internal(lock);
+ return *result;
+ }
+ T& get_sh()
+ {
+ boost::unique_lock<boost::mutex> lock(this->mutex);
+ return get_sh(lock);
+ }
+
+ void set_value_at_thread_exit(T& result_)
+ {
+ unique_lock<boost::mutex> lk(this->mutex);
+ if (this->has_value(lk))
+ throw_exception(promise_already_satisfied());
+ result= &result_;
+ this->is_constructed = true;
+ detail::make_ready_at_thread_exit(shared_from_this());
+ }
+
+ private:
+ shared_state(shared_state const&);
+ shared_state& operator=(shared_state const&);
+ };
+
+ template<>
+ struct shared_state<void>:
+ detail::shared_state_base
+ {
+ typedef void shared_future_get_result_type;
+ typedef void move_dest_type;
+
+ shared_state()
+ {}
+
+ shared_state(exceptional_ptr const& ex):
+ detail::shared_state_base(ex)
+ {}
+
+ void mark_finished_with_result_internal(boost::unique_lock<boost::mutex>& lock)
+ {
+ mark_finished_internal(lock);
+ }
+
+ void mark_finished_with_result()
+ {
+ boost::unique_lock<boost::mutex> lock(this->mutex);
+ mark_finished_with_result_internal(lock);
+ }
+
+ virtual void get(boost::unique_lock<boost::mutex>& lock)
+ {
+ this->wait_internal(lock);
+ }
+ void get()
+ {
+ boost::unique_lock<boost::mutex> lock(this->mutex);
+ this->get(lock);
+ }
+
+ virtual void get_sh(boost::unique_lock<boost::mutex>& lock)
+ {
+ this->wait_internal(lock);
+ }
+ void get_sh()
+ {
+ boost::unique_lock<boost::mutex> lock(this->mutex);
+ this->get_sh(lock);
+ }
+
+ void set_value_at_thread_exit()
+ {
+ unique_lock<boost::mutex> lk(this->mutex);
+ if (this->has_value(lk))
+ {
+ throw_exception(promise_already_satisfied());
+ }
+ this->is_constructed = true;
+ detail::make_ready_at_thread_exit(shared_from_this());
+ }
+ private:
+ shared_state(shared_state const&);
+ shared_state& operator=(shared_state const&);
+ };
+
+ /////////////////////////
+ /// future_async_shared_state_base
+ /////////////////////////
+ template<typename Rp>
+ struct future_async_shared_state_base: shared_state<Rp>
+ {
+ typedef shared_state<Rp> base_type;
+ protected:
+#ifdef BOOST_THREAD_FUTURE_BLOCKING
+ boost::thread thr_;
+ void join()
+ {
+ if (this_thread::get_id() == thr_.get_id())
+ {
+ thr_.detach();
+ return;
+ }
+ if (thr_.joinable()) thr_.join();
+ }
+#endif
+ public:
+ future_async_shared_state_base()
+ {
+ this->set_async();
+ }
+
+ ~future_async_shared_state_base()
+ {
+#ifdef BOOST_THREAD_FUTURE_BLOCKING
+ join();
+#endif
+ }
+
+ virtual void wait(boost::unique_lock<boost::mutex>& lk, bool rethrow)
+ {
+#ifdef BOOST_THREAD_FUTURE_BLOCKING
+ {
+ relocker rlk(lk);
+ join();
+ }
+#endif
+ this->base_type::wait(lk, rethrow);
+ }
+ };
+
+ /////////////////////////
+ /// future_async_shared_state
+ /////////////////////////
+ template<typename Rp, typename Fp>
+ struct future_async_shared_state: future_async_shared_state_base<Rp>
+ {
+ future_async_shared_state()
+ {
+ }
+
+ void init(BOOST_THREAD_FWD_REF(Fp) f)
+ {
+#ifdef BOOST_THREAD_FUTURE_BLOCKING
+ this->thr_ = thread(&future_async_shared_state::run, static_shared_from_this(this), boost::forward<Fp>(f));
+#else
+ thread(&future_async_shared_state::run, static_shared_from_this(this), boost::forward<Fp>(f)).detach();
+#endif
+ }
+
+ static void run(shared_ptr<future_async_shared_state> that, BOOST_THREAD_FWD_REF(Fp) f)
+ {
+ try
+ {
+ that->mark_finished_with_result(f());
+ }
+ catch(...)
+ {
+ that->mark_exceptional_finish();
+ }
+ }
+ };
+
+ template<typename Fp>
+ struct future_async_shared_state<void, Fp>: public future_async_shared_state_base<void>
+ {
+ void init(BOOST_THREAD_FWD_REF(Fp) f)
+ {
+#ifdef BOOST_THREAD_FUTURE_BLOCKING
+ this->thr_ = thread(&future_async_shared_state::run, static_shared_from_this(this), boost::move(f));
+#else
+ thread(&future_async_shared_state::run, static_shared_from_this(this), boost::move(f)).detach();
+#endif
+ }
+
+ static void run(shared_ptr<future_async_shared_state> that, BOOST_THREAD_FWD_REF(Fp) f)
+ {
+ try
+ {
+ f();
+ that->mark_finished_with_result();
+ }
+ catch(...)
+ {
+ that->mark_exceptional_finish();
+ }
+ }
+ };
+
+ template<typename Rp, typename Fp>
+ struct future_async_shared_state<Rp&, Fp>: future_async_shared_state_base<Rp&>
+ {
+ void init(BOOST_THREAD_FWD_REF(Fp) f)
+ {
+#ifdef BOOST_THREAD_FUTURE_BLOCKING
+ this->thr_ = thread(&future_async_shared_state::run, static_shared_from_this(this), boost::move(f));
+#else
+ thread(&future_async_shared_state::run, static_shared_from_this(this), boost::move(f)).detach();
+#endif
+ }
+
+ static void run(shared_ptr<future_async_shared_state> that, BOOST_THREAD_FWD_REF(Fp) f)
+ {
+ try
+ {
+ that->mark_finished_with_result(f());
+ }
+ catch(...)
+ {
+ that->mark_exceptional_finish();
+ }
+ }
+ };
+
+ //////////////////////////
+ /// future_deferred_shared_state
+ //////////////////////////
+ template<typename Rp, typename Fp>
+ struct future_deferred_shared_state: shared_state<Rp>
+ {
+ typedef shared_state<Rp> base_type;
+ Fp func_;
+
+ public:
+ explicit future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f)
+ : func_(boost::move(f))
+ {
+ this->set_deferred();
+ }
+
+ virtual void execute(boost::unique_lock<boost::mutex>& lck) {
+ try
+ {
+ Fp local_fuct=boost::move(func_);
+ relocker relock(lck);
+ Rp res = local_fuct();
+ relock.lock();
+ this->mark_finished_with_result_internal(boost::move(res), lck);
+ }
+ catch (...)
+ {
+ this->mark_exceptional_finish_internal(current_exception(), lck);
+ }
+ }
+ };
+ template<typename Rp, typename Fp>
+ struct future_deferred_shared_state<Rp&,Fp>: shared_state<Rp&>
+ {
+ typedef shared_state<Rp&> base_type;
+ Fp func_;
+
+ public:
+ explicit future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f)
+ : func_(boost::move(f))
+ {
+ this->set_deferred();
+ }
+
+ virtual void execute(boost::unique_lock<boost::mutex>& lck) {
+ try
+ {
+ this->mark_finished_with_result_internal(func_(), lck);
+ }
+ catch (...)
+ {
+ this->mark_exceptional_finish_internal(current_exception(), lck);
+ }
+ }
+ };
+
+ template<typename Fp>
+ struct future_deferred_shared_state<void,Fp>: shared_state<void>
+ {
+ typedef shared_state<void> base_type;
+ Fp func_;
+
+ public:
+ explicit future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f)
+ : func_(boost::move(f))
+ {
+ this->set_deferred();
+ }
+
+ virtual void execute(boost::unique_lock<boost::mutex>& lck) {
+ try
+ {
+ Fp local_fuct=boost::move(func_);
+ relocker relock(lck);
+ local_fuct();
+ relock.lock();
+ this->mark_finished_with_result_internal(lck);
+ }
+ catch (...)
+ {
+ this->mark_exceptional_finish_internal(current_exception(), lck);
+ }
+ }
+ };
+
+ class future_waiter
+ {
+ public:
+ typedef std::vector<int>::size_type count_type;
+ private:
+ struct registered_waiter;
+ struct registered_waiter
+ {
+ boost::shared_ptr<detail::shared_state_base> future_;
+ detail::shared_state_base::notify_when_ready_handle handle;
+ count_type index;
+
+ registered_waiter(boost::shared_ptr<detail::shared_state_base> const& a_future,
+ detail::shared_state_base::notify_when_ready_handle handle_,
+ count_type index_):
+ future_(a_future),handle(handle_),index(index_)
+ {}
+ };
+
+ struct all_futures_lock
+ {
+#ifdef _MANAGED
+ typedef std::ptrdiff_t count_type_portable;
+#else
+ typedef count_type count_type_portable;
+#endif
+ count_type_portable count;
+ boost::scoped_array<boost::unique_lock<boost::mutex> > locks;
+
+ all_futures_lock(std::vector<registered_waiter>& futures):
+ count(futures.size()),locks(new boost::unique_lock<boost::mutex>[count])
+ {
+ for(count_type_portable i=0;i<count;++i)
+ {
+ locks[i]=BOOST_THREAD_MAKE_RV_REF(boost::unique_lock<boost::mutex>(futures[i].future_->mutex));
+ }
+ }
+
+ void lock()
+ {
+ boost::lock(locks.get(),locks.get()+count);
+ }
+
+ void unlock()
+ {
+ for(count_type_portable i=0;i<count;++i)
+ {
+ locks[i].unlock();
+ }
+ }
+ };
+
+ boost::condition_variable_any cv;
+ std::vector<registered_waiter> futures_;
+ count_type future_count;
+
+ public:
+ future_waiter():
+ future_count(0)
+ {}
+
+ template<typename F>
+ void add(F& f)
+ {
+ if(f.future_)
+ {
+ registered_waiter waiter(f.future_,f.future_->notify_when_ready(cv),future_count);
+ try {
+ futures_.push_back(waiter);
+ } catch(...) {
+ f.future_->unnotify_when_ready(waiter.handle);
+ throw;
+ }
+ }
+ ++future_count;
+ }
+
+#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+ template<typename F1, typename... Fs>
+ void add(F1& f1, Fs&... fs)
+ {
+ add(f1); add(fs...);
+ }
+#endif
+
+ count_type wait()
+ {
+ all_futures_lock lk(futures_);
+ for(;;)
+ {
+ for(count_type i=0;i<futures_.size();++i)
+ {
+ if(futures_[i].future_->done)
+ {
+ return futures_[i].index;
+ }
+ }
+ cv.wait(lk);
+ }
+ }
+
+ ~future_waiter()
+ {
+ for(count_type i=0;i<futures_.size();++i)
+ {
+ futures_[i].future_->unnotify_when_ready(futures_[i].handle);
+ }
+ }
+ };
+
+ }
+
+ template <typename R>
+ class BOOST_THREAD_FUTURE;
+
+ template <typename R>
+ class shared_future;
+
+ template<typename T>
+ struct is_future_type<BOOST_THREAD_FUTURE<T> > : true_type
+ {
+ };
+
+ template<typename T>
+ struct is_future_type<shared_future<T> > : true_type
+ {
+ };
+
+// template<typename Iterator>
+// typename boost::disable_if<is_future_type<Iterator>,Iterator>::type wait_for_any(Iterator begin,Iterator end)
+// {
+// if(begin==end)
+// return end;
+//
+// detail::future_waiter waiter;
+// for(Iterator current=begin;current!=end;++current)
+// {
+// waiter.add(*current);
+// }
+// return boost::next(begin,waiter.wait());
+// }
+
+#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+ template<typename F1,typename F2>
+ typename boost::enable_if<is_future_type<F1>,typename detail::future_waiter::count_type>::type wait_for_any(F1& f1,F2& f2)
+ {
+ detail::future_waiter waiter;
+ waiter.add(f1);
+ waiter.add(f2);
+ return waiter.wait();
+ }
+
+ template<typename F1,typename F2,typename F3>
+ typename detail::future_waiter::count_type wait_for_any(F1& f1,F2& f2,F3& f3)
+ {
+ detail::future_waiter waiter;
+ waiter.add(f1);
+ waiter.add(f2);
+ waiter.add(f3);
+ return waiter.wait();
+ }
+
+ template<typename F1,typename F2,typename F3,typename F4>
+ typename detail::future_waiter::count_type wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4)
+ {
+ detail::future_waiter waiter;
+ waiter.add(f1);
+ waiter.add(f2);
+ waiter.add(f3);
+ waiter.add(f4);
+ return waiter.wait();
+ }
+
+ template<typename F1,typename F2,typename F3,typename F4,typename F5>
+ typename detail::future_waiter::count_type wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5)
+ {
+ detail::future_waiter waiter;
+ waiter.add(f1);
+ waiter.add(f2);
+ waiter.add(f3);
+ waiter.add(f4);
+ waiter.add(f5);
+ return waiter.wait();
+ }
+#else
+ template<typename F1, typename... Fs>
+ typename boost::enable_if<is_future_type<F1>, typename detail::future_waiter::count_type>::type
+ wait_for_any(F1& f1, Fs&... fs)
+ {
+ detail::future_waiter waiter;
+ waiter.add(f1, fs...);
+ return waiter.wait();
+ }
+#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+ template <typename R>
+ class promise;
+
+ template <typename R>
+ class packaged_task;
+
+ namespace detail
+ {
+ /// Common implementation for all the futures independently of the return type
+ class base_future
+ {
+ public:
+ };
+ /// Common implementation for future and shared_future.
+ template <typename R>
+ class basic_future : public base_future
+ {
+ protected:
+ public:
+
+ typedef boost::shared_ptr<detail::shared_state<R> > future_ptr;
+ typedef typename detail::shared_state<R>::move_dest_type move_dest_type;
+
+ static //BOOST_CONSTEXPR
+ future_ptr make_exceptional_future_ptr(exceptional_ptr const& ex) {
+ return future_ptr(new detail::shared_state<R>(ex));
+ }
+
+ future_ptr future_;
+
+ basic_future(future_ptr a_future):
+ future_(a_future)
+ {
+ }
+
+ public:
+ typedef future_state::state state;
+
+ BOOST_THREAD_MOVABLE_ONLY(basic_future)
+ basic_future(): future_() {}
+
+
+ //BOOST_CONSTEXPR
+ basic_future(exceptional_ptr const& ex)
+ : future_(make_exceptional_future_ptr(ex))
+ {
+ }
+
+ ~basic_future() {
+ }
+
+ basic_future(BOOST_THREAD_RV_REF(basic_future) other) BOOST_NOEXCEPT:
+ future_(BOOST_THREAD_RV(other).future_)
+ {
+ BOOST_THREAD_RV(other).future_.reset();
+ }
+ basic_future& operator=(BOOST_THREAD_RV_REF(basic_future) other) BOOST_NOEXCEPT
+ {
+ future_=BOOST_THREAD_RV(other).future_;
+ BOOST_THREAD_RV(other).future_.reset();
+ return *this;
+ }
+ void swap(basic_future& that) BOOST_NOEXCEPT
+ {
+ future_.swap(that.future_);
+ }
+ // functions to check state, and wait for ready
+ state get_state(boost::unique_lock<boost::mutex>& lk) const
+ {
+ if(!future_)
+ {
+ return future_state::uninitialized;
+ }
+ return future_->get_state(lk);
+ }
+ state get_state() const
+ {
+ if(!future_)
+ {
+ return future_state::uninitialized;
+ }
+ return future_->get_state();
+ }
+
+ bool is_ready() const
+ {
+ return get_state()==future_state::ready;
+ }
+
+ bool is_ready(boost::unique_lock<boost::mutex>& lk) const
+ {
+ return get_state(lk)==future_state::ready;
+ }
+ bool has_exception() const
+ {
+ return future_ && future_->has_exception();
+ }
+
+ bool has_value() const
+ {
+ return future_ && future_->has_value();
+ }
+
+ launch launch_policy(boost::unique_lock<boost::mutex>& lk) const
+ {
+ if ( future_ ) return future_->launch_policy(lk);
+ else return launch(launch::none);
+ }
+
+ launch launch_policy() const
+ {
+ if ( future_ ) {
+ boost::unique_lock<boost::mutex> lk(this->future_->mutex);
+ return future_->launch_policy(lk);
+ }
+ else return launch(launch::none);
+ }
+
+ exception_ptr get_exception_ptr()
+ {
+ return future_
+ ? future_->get_exception_ptr()
+ : exception_ptr();
+ }
+
+ bool valid() const BOOST_NOEXCEPT
+ {
+ return future_ != 0 && future_->valid();
+ }
+
+ void wait() const
+ {
+ if(!future_)
+ {
+ boost::throw_exception(future_uninitialized());
+ }
+ future_->wait(false);
+ }
+
+ typedef detail::shared_state_base::notify_when_ready_handle notify_when_ready_handle;
+
+ boost::mutex& mutex() {
+ if(!future_)
+ {
+ boost::throw_exception(future_uninitialized());
+ }
+ return future_->mutex;
+ };
+
+ notify_when_ready_handle notify_when_ready(boost::condition_variable_any& cv)
+ {
+ if(!future_)
+ {
+ boost::throw_exception(future_uninitialized());
+ }
+ return future_->notify_when_ready(cv);
+ }
+
+ void unnotify_when_ready(notify_when_ready_handle h)
+ {
+ if(!future_)
+ {
+ boost::throw_exception(future_uninitialized());
+ }
+ return future_->unnotify_when_ready(h);
+ }
+
+#if defined BOOST_THREAD_USES_DATETIME
+ template<typename Duration>
+ bool timed_wait(Duration const& rel_time) const
+ {
+ return timed_wait_until(boost::get_system_time()+rel_time);
+ }
+
+ bool timed_wait_until(boost::system_time const& abs_time) const
+ {
+ if(!future_)
+ {
+ boost::throw_exception(future_uninitialized());
+ }
+ return future_->timed_wait_until(abs_time);
+ }
+#endif
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ future_status
+ wait_for(const chrono::duration<Rep, Period>& rel_time) const
+ {
+ return wait_until(chrono::steady_clock::now() + rel_time);
+
+ }
+ template <class Clock, class Duration>
+ future_status
+ wait_until(const chrono::time_point<Clock, Duration>& abs_time) const
+ {
+ if(!future_)
+ {
+ boost::throw_exception(future_uninitialized());
+ }
+ return future_->wait_until(abs_time);
+ }
+#endif
+
+ };
+
+ } // detail
+ BOOST_THREAD_DCL_MOVABLE_BEG(R) detail::basic_future<R> BOOST_THREAD_DCL_MOVABLE_END
+
+ namespace detail
+ {
+#if (!defined _MSC_VER || _MSC_VER >= 1400) // _MSC_VER == 1400 on MSVC 2005
+ template <class Rp, class Fp>
+ BOOST_THREAD_FUTURE<Rp>
+ make_future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
+
+ template <class Rp, class Fp>
+ BOOST_THREAD_FUTURE<Rp>
+ make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
+#endif // #if (!defined _MSC_VER || _MSC_VER >= 1400)
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
+ template<typename F, typename Rp, typename Fp>
+ struct future_deferred_continuation_shared_state;
+ template<typename F, typename Rp, typename Fp>
+ struct future_async_continuation_shared_state;
+
+ template <class F, class Rp, class Fp>
+ BOOST_THREAD_FUTURE<Rp>
+ make_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
+
+ template <class F, class Rp, class Fp>
+ BOOST_THREAD_FUTURE<Rp>
+ make_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
+
+ template<typename F, typename Rp, typename Fp>
+ BOOST_THREAD_FUTURE<Rp>
+ make_shared_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
+
+ template<typename F, typename Rp, typename Fp>
+ BOOST_THREAD_FUTURE<Rp>
+ make_shared_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
+
+ #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
+ template<typename Ex, typename F, typename Rp, typename Fp>
+ BOOST_THREAD_FUTURE<Rp>
+ make_future_executor_continuation_shared_state(Ex& ex, boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
+
+ template<typename Ex, typename F, typename Rp, typename Fp>
+ BOOST_THREAD_FUTURE<Rp>
+ make_shared_future_executor_continuation_shared_state(Ex& ex, boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
+
+ template <class Rp, class Fp, class Executor>
+ BOOST_THREAD_FUTURE<Rp>
+ make_future_executor_shared_state(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f);
+ #endif
+#endif
+#if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
+ template<typename F, typename Rp>
+ struct future_unwrap_shared_state;
+ template <class F, class Rp>
+ inline BOOST_THREAD_FUTURE<Rp>
+ make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f);
+#endif
+ }
+#if defined(BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY)
+ template< typename InputIterator>
+ typename boost::disable_if<is_future_type<InputIterator>,
+ BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type> >
+ >::type
+ when_all(InputIterator first, InputIterator last);
+
+ inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_all();
+
+ #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template< typename T0, typename ...T>
+ BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
+ when_all(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures);
+ #endif
+
+ template< typename InputIterator>
+ typename boost::disable_if<is_future_type<InputIterator>,
+ BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type> >
+ >::type
+ when_any(InputIterator first, InputIterator last);
+
+ inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_any();
+
+ #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template< typename T0, typename ...T>
+ BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
+ when_any(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures);
+ #endif
+#endif // BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
+
+
+ template <typename R>
+ class BOOST_THREAD_FUTURE : public detail::basic_future<R>
+ {
+ private:
+ typedef detail::basic_future<R> base_type;
+ typedef typename base_type::future_ptr future_ptr;
+
+ friend class shared_future<R>;
+ friend class promise<R>;
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
+ template <typename, typename, typename>
+ friend struct detail::future_async_continuation_shared_state;
+ template <typename, typename, typename>
+ friend struct detail::future_deferred_continuation_shared_state;
+
+ template <class F, class Rp, class Fp>
+ friend BOOST_THREAD_FUTURE<Rp>
+ detail::make_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
+
+ template <class F, class Rp, class Fp>
+ friend BOOST_THREAD_FUTURE<Rp>
+ detail::make_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
+
+ template<typename F, typename Rp, typename Fp>
+ friend BOOST_THREAD_FUTURE<Rp>
+ detail::make_shared_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
+
+ template<typename F, typename Rp, typename Fp>
+ friend BOOST_THREAD_FUTURE<Rp>
+ detail::make_shared_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
+
+ #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
+ template<typename Ex, typename F, typename Rp, typename Fp>
+ friend BOOST_THREAD_FUTURE<Rp>
+ detail::make_future_executor_continuation_shared_state(Ex& ex, boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
+
+ template<typename Ex, typename F, typename Rp, typename Fp>
+ friend BOOST_THREAD_FUTURE<Rp>
+ detail::make_shared_future_executor_continuation_shared_state(Ex& ex, boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
+
+ template <class Rp, class Fp, class Executor>
+ friend BOOST_THREAD_FUTURE<Rp>
+ detail::make_future_executor_shared_state(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f);
+ #endif
+#endif
+#if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
+ template<typename F, typename Rp>
+ friend struct detail::future_unwrap_shared_state;
+ template <class F, class Rp>
+ friend BOOST_THREAD_FUTURE<Rp>
+ detail::make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f);
+#endif
+#if defined(BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY)
+ template< typename InputIterator>
+ friend typename boost::disable_if<is_future_type<InputIterator>,
+ BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type> >
+ >::type
+ when_all(InputIterator first, InputIterator last);
+
+ //friend inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_all();
+
+ #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template< typename T0, typename ...T>
+ friend BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
+ when_all(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures);
+ #endif
+
+ template< typename InputIterator>
+ friend typename boost::disable_if<is_future_type<InputIterator>,
+ BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type> >
+ >::type
+ when_any(InputIterator first, InputIterator last);
+
+ //friend inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_any();
+
+ #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template< typename T0, typename ...T>
+ friend BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
+ when_any(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures);
+ #endif
+#endif // BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+ template <class> friend class packaged_task; // todo check if this works in windows
+#else
+ friend class packaged_task<R>;
+#endif
+ friend class detail::future_waiter;
+
+ template <class Rp, class Fp>
+ friend BOOST_THREAD_FUTURE<Rp>
+ detail::make_future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
+
+ template <class Rp, class Fp>
+ friend BOOST_THREAD_FUTURE<Rp>
+ detail::make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
+
+ typedef typename base_type::move_dest_type move_dest_type;
+
+ BOOST_THREAD_FUTURE(future_ptr a_future):
+ base_type(a_future)
+ {
+ }
+
+ public:
+ BOOST_THREAD_MOVABLE_ONLY(BOOST_THREAD_FUTURE)
+ typedef future_state::state state;
+ typedef R value_type; // EXTENSION
+
+ BOOST_CONSTEXPR BOOST_THREAD_FUTURE() {}
+ //BOOST_CONSTEXPR
+ BOOST_THREAD_FUTURE(exceptional_ptr const& ex):
+ base_type(ex) {}
+
+ ~BOOST_THREAD_FUTURE() {
+ }
+
+ BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT:
+ base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
+ {
+ }
+ inline BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R> >) other); // EXTENSION
+
+ explicit BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(shared_future<R>) other) :
+ base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
+ {}
+
+ BOOST_THREAD_FUTURE& operator=(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT
+ {
+ this->base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
+ return *this;
+ }
+
+ shared_future<R> share()
+ {
+ return shared_future<R>(::boost::move(*this));
+ }
+
+ void swap(BOOST_THREAD_FUTURE& other)
+ {
+ static_cast<base_type*>(this)->swap(other);
+ }
+
+ // todo this function must be private and friendship provided to the internal users.
+ void set_async()
+ {
+ this->future_->set_async();
+ }
+ // todo this function must be private and friendship provided to the internal users.
+ void set_deferred()
+ {
+ this->future_->set_deferred();
+ }
+ bool run_if_is_deferred() {
+ return this->future_->run_if_is_deferred();
+ }
+ bool run_if_is_deferred_or_ready() {
+ return this->future_->run_if_is_deferred_or_ready();
+ }
+ // retrieving the value
+ move_dest_type get()
+ {
+ if (this->future_ == 0)
+ {
+ boost::throw_exception(future_uninitialized());
+ }
+ unique_lock<boost::mutex> lk(this->future_->mutex);
+ if (! this->future_->valid(lk))
+ {
+ boost::throw_exception(future_uninitialized());
+ }
+#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
+ this->future_->invalidate(lk);
+#endif
+ return this->future_->get(lk);
+ }
+
+ template <typename R2>
+ typename boost::disable_if< is_void<R2>, move_dest_type>::type
+ get_or(BOOST_THREAD_RV_REF(R2) v)
+ {
+
+ if (this->future_ == 0)
+ {
+ boost::throw_exception(future_uninitialized());
+ }
+ unique_lock<boost::mutex> lk(this->future_->mutex);
+ if (! this->future_->valid(lk))
+ {
+ boost::throw_exception(future_uninitialized());
+ }
+ this->future_->wait(lk, false);
+#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
+ this->future_->invalidate(lk);
+#endif
+
+ if (this->future_->has_value(lk)) {
+ return this->future_->get(lk);
+ }
+ else {
+ return boost::move(v);
+ }
+ }
+
+ template <typename R2>
+ typename boost::disable_if< is_void<R2>, move_dest_type>::type
+ get_or(R2 const& v) // EXTENSION
+ {
+ if (this->future_ == 0)
+ {
+ boost::throw_exception(future_uninitialized());
+ }
+ unique_lock<boost::mutex> lk(this->future_->mutex);
+ if (! this->future_->valid(lk))
+ {
+ boost::throw_exception(future_uninitialized());
+ }
+ this->future_->wait(lk, false);
+#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
+ this->future_->invalidate(lk);
+#endif
+ if (this->future_->has_value(lk)) {
+ return this->future_->get(lk);
+ }
+ else {
+ return v;
+ }
+ }
+
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
+ template<typename F>
+ inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
+ then(BOOST_THREAD_FWD_REF(F) func); // EXTENSION
+ template<typename F>
+ inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
+ then(launch policy, BOOST_THREAD_FWD_REF(F) func); // EXTENSION
+ #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
+ template<typename Ex, typename F>
+ inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
+ then(Ex& ex, BOOST_THREAD_FWD_REF(F) func); // EXTENSION
+ #endif
+
+ template <typename R2>
+ inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type
+ fallback_to(BOOST_THREAD_RV_REF(R2) v); // EXTENSION
+ template <typename R2>
+ inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type
+ fallback_to(R2 const& v); // EXTENSION
+
+#endif
+
+ };
+
+ BOOST_THREAD_DCL_MOVABLE_BEG(T) BOOST_THREAD_FUTURE<T> BOOST_THREAD_DCL_MOVABLE_END
+
+ template <typename R2>
+ class BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> > : public detail::basic_future<BOOST_THREAD_FUTURE<R2> >
+ {
+ typedef BOOST_THREAD_FUTURE<R2> R;
+
+ private:
+ typedef detail::basic_future<R> base_type;
+ typedef typename base_type::future_ptr future_ptr;
+
+ friend class shared_future<R>;
+ friend class promise<R>;
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
+ template <typename, typename, typename>
+ friend struct detail::future_async_continuation_shared_state;
+ template <typename, typename, typename>
+ friend struct detail::future_deferred_continuation_shared_state;
+
+ template <class F, class Rp, class Fp>
+ friend BOOST_THREAD_FUTURE<Rp>
+ detail::make_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
+
+ template <class F, class Rp, class Fp>
+ friend BOOST_THREAD_FUTURE<Rp>
+ detail::make_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
+
+ template<typename F, typename Rp, typename Fp>
+ friend BOOST_THREAD_FUTURE<Rp>
+ detail::make_shared_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
+
+ template<typename F, typename Rp, typename Fp>
+ friend BOOST_THREAD_FUTURE<Rp>
+ detail::make_shared_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
+
+ #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
+ template<typename Ex, typename F, typename Rp, typename Fp>
+ friend BOOST_THREAD_FUTURE<Rp>
+ detail::make_future_executor_continuation_shared_state(Ex& ex, boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
+
+ template<typename Ex, typename F, typename Rp, typename Fp>
+ friend BOOST_THREAD_FUTURE<Rp>
+ detail::make_shared_future_executor_continuation_shared_state(Ex& ex, boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
+
+ template <class Rp, class Fp, class Executor>
+ friend BOOST_THREAD_FUTURE<Rp>
+ detail::make_future_executor_shared_state(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f);
+ #endif
+
+#endif
+#if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
+ template<typename F, typename Rp>
+ friend struct detail::future_unwrap_shared_state;
+ template <class F, class Rp>
+ friend BOOST_THREAD_FUTURE<Rp>
+ detail::make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f);
+#endif
+#if defined(BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY)
+ template< typename InputIterator>
+ friend typename boost::disable_if<is_future_type<InputIterator>,
+ BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type> >
+ >::type
+ when_all(InputIterator first, InputIterator last);
+
+ friend inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_all();
+
+ #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template< typename T0, typename ...T>
+ friend BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
+ when_all(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures);
+ #endif
+
+ template< typename InputIterator>
+ friend typename boost::disable_if<is_future_type<InputIterator>,
+ BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type> >
+ >::type
+ when_any(InputIterator first, InputIterator last);
+
+ friend inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_any();
+
+ #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template< typename T0, typename ...T>
+ friend BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
+ when_any(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures);
+ #endif
+#endif // BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
+
+ #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+ template <class> friend class packaged_task; // todo check if this works in windows
+ #else
+ friend class packaged_task<R>;
+ #endif
+ friend class detail::future_waiter;
+
+ template <class Rp, class Fp>
+ friend BOOST_THREAD_FUTURE<Rp>
+ detail::make_future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
+
+ template <class Rp, class Fp>
+ friend BOOST_THREAD_FUTURE<Rp>
+ detail::make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
+
+ typedef typename base_type::move_dest_type move_dest_type;
+
+ BOOST_THREAD_FUTURE(future_ptr a_future):
+ base_type(a_future)
+ {
+ }
+ public:
+
+ BOOST_THREAD_MOVABLE_ONLY(BOOST_THREAD_FUTURE)
+ typedef future_state::state state;
+ typedef R value_type; // EXTENSION
+
+ BOOST_CONSTEXPR BOOST_THREAD_FUTURE() {}
+ //BOOST_CONSTEXPR
+ BOOST_THREAD_FUTURE(exceptional_ptr const& ex):
+ base_type(ex) {}
+
+ ~BOOST_THREAD_FUTURE() {
+ }
+
+ BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT:
+ base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
+ {
+ }
+
+ BOOST_THREAD_FUTURE& operator=(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT
+ {
+ this->base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
+ return *this;
+ }
+
+ shared_future<R> share()
+ {
+ return shared_future<R>(::boost::move(*this));
+ }
+
+ void swap(BOOST_THREAD_FUTURE& other)
+ {
+ static_cast<base_type*>(this)->swap(other);
+ }
+
+ // todo this function must be private and friendship provided to the internal users.
+ void set_async()
+ {
+ this->future_->set_async();
+ }
+ // todo this function must be private and friendship provided to the internal users.
+ void set_deferred()
+ {
+ this->future_->set_deferred();
+ }
+ bool run_if_is_deferred() {
+ return this->future_->run_if_is_deferred();
+ }
+ bool run_if_is_deferred_or_ready() {
+ return this->future_->run_if_is_deferred_or_ready();
+ }
+ // retrieving the value
+ move_dest_type get()
+ {
+ if (this->future_ == 0)
+ {
+ boost::throw_exception(future_uninitialized());
+ }
+ unique_lock<boost::mutex> lk(this->future_->mutex);
+ if (! this->future_->valid(lk))
+ {
+ boost::throw_exception(future_uninitialized());
+ }
+ #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
+ this->future_->invalidate(lk);
+ #endif
+ return this->future_->get(lk);
+ }
+ move_dest_type get_or(BOOST_THREAD_RV_REF(R) v) // EXTENSION
+ {
+ if (this->future_ == 0)
+ {
+ boost::throw_exception(future_uninitialized());
+ }
+ unique_lock<boost::mutex> lk(this->future_->mutex);
+ if (! this->future_->valid(lk))
+ {
+ boost::throw_exception(future_uninitialized());
+ }
+ this->future_->wait(lk, false);
+ #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
+ this->future_->invalidate(lk);
+ #endif
+ if (this->future_->has_value(lk)) return this->future_->get(lk);
+ else return boost::move(v);
+ }
+
+ move_dest_type get_or(R const& v) // EXTENSION
+ {
+ if (this->future_ == 0)
+ {
+ boost::throw_exception(future_uninitialized());
+ }
+ unique_lock<boost::mutex> lk(this->future_->mutex);
+ if (! this->future_->valid(lk))
+ {
+ boost::throw_exception(future_uninitialized());
+ }
+ this->future_->wait(lk, false);
+ #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
+ this->future_->invalidate(lk);
+ #endif
+ if (this->future_->has_value(lk)) return this->future_->get(lk);
+ else return v;
+ }
+
+
+ #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
+ template<typename F>
+ inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
+ then(BOOST_THREAD_FWD_REF(F) func); // EXTENSION
+ template<typename F>
+ inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
+ then(launch policy, BOOST_THREAD_FWD_REF(F) func); // EXTENSION
+ #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
+ template<typename Ex, typename F>
+ inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
+ then(Ex &ex, BOOST_THREAD_FWD_REF(F) func); // EXTENSION
+ #endif
+ #endif
+
+ #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
+ inline
+ BOOST_THREAD_FUTURE<R2>
+ unwrap(); // EXTENSION
+ #endif
+
+ };
+
+ template <typename R>
+ class shared_future : public detail::basic_future<R>
+ {
+ typedef detail::basic_future<R> base_type;
+ typedef typename base_type::future_ptr future_ptr;
+
+ friend class detail::future_waiter;
+ friend class promise<R>;
+
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
+ template <typename, typename, typename>
+ friend struct detail::future_async_continuation_shared_state;
+ template <typename, typename, typename>
+ friend struct detail::future_deferred_continuation_shared_state;
+
+ template <class F, class Rp, class Fp>
+ friend BOOST_THREAD_FUTURE<Rp>
+ detail::make_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
+
+ template <class F, class Rp, class Fp>
+ friend BOOST_THREAD_FUTURE<Rp>
+ detail::make_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
+#endif
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+ template <class> friend class packaged_task;// todo check if this works in windows
+#else
+ friend class packaged_task<R>;
+#endif
+ shared_future(future_ptr a_future):
+ base_type(a_future)
+ {}
+
+ public:
+ BOOST_THREAD_COPYABLE_AND_MOVABLE(shared_future)
+ typedef R value_type; // EXTENSION
+
+ shared_future(shared_future const& other):
+ base_type(other.future_)
+ {}
+
+ typedef future_state::state state;
+
+ BOOST_CONSTEXPR shared_future()
+ {}
+ //BOOST_CONSTEXPR
+ shared_future(exceptional_ptr const& ex):
+ base_type(ex) {}
+ ~shared_future()
+ {}
+
+ shared_future& operator=(BOOST_THREAD_COPY_ASSIGN_REF(shared_future) other)
+ {
+ this->future_ = other.future_;
+ return *this;
+ }
+
+ shared_future(BOOST_THREAD_RV_REF(shared_future) other) BOOST_NOEXCEPT :
+ base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
+ {
+ }
+ shared_future(BOOST_THREAD_RV_REF( BOOST_THREAD_FUTURE<R> ) other) BOOST_NOEXCEPT :
+ base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
+ {
+ }
+
+ shared_future& operator=(BOOST_THREAD_RV_REF(shared_future) other) BOOST_NOEXCEPT
+ {
+ base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
+ return *this;
+ }
+ shared_future& operator=(BOOST_THREAD_RV_REF( BOOST_THREAD_FUTURE<R> ) other) BOOST_NOEXCEPT
+ {
+ base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
+ return *this;
+ }
+
+ void swap(shared_future& other) BOOST_NOEXCEPT
+ {
+ static_cast<base_type*>(this)->swap(other);
+ }
+ bool run_if_is_deferred() {
+ return this->future_->run_if_is_deferred();
+ }
+ bool run_if_is_deferred_or_ready() {
+ return this->future_->run_if_is_deferred_or_ready();
+ }
+ // retrieving the value
+ typename detail::shared_state<R>::shared_future_get_result_type get() const
+ {
+ if(!this->future_)
+ {
+ boost::throw_exception(future_uninitialized());
+ }
+ return this->future_->get_sh();
+ }
+
+ template <typename R2>
+ typename boost::disable_if< is_void<R2>, typename detail::shared_state<R>::shared_future_get_result_type>::type
+ get_or(BOOST_THREAD_RV_REF(R2) v) const // EXTENSION
+ {
+ if(!this->future_)
+ {
+ boost::throw_exception(future_uninitialized());
+ }
+ this->future_->wait();
+ if (this->future_->has_value()) return this->future_->get_sh();
+ else return boost::move(v);
+ }
+
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
+ template<typename F>
+ inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future)>::type>
+ then(BOOST_THREAD_FWD_REF(F) func) const; // EXTENSION
+ template<typename F>
+ inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future)>::type>
+ then(launch policy, BOOST_THREAD_FWD_REF(F) func) const; // EXTENSION
+ #ifdef BOOST_THREAD_PROVIDES_EXECUTORS
+ template<typename Ex, typename F>
+ inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future)>::type>
+ then(Ex& ex, BOOST_THREAD_FWD_REF(F) func) const; // EXTENSION
+ #endif
+#endif
+
+ };
+
+ BOOST_THREAD_DCL_MOVABLE_BEG(T) shared_future<T> BOOST_THREAD_DCL_MOVABLE_END
+
+ template <typename R>
+ class promise
+ {
+ typedef boost::shared_ptr<detail::shared_state<R> > future_ptr;
+
+ typedef typename detail::shared_state<R>::source_reference_type source_reference_type;
+ typedef typename detail::shared_state<R>::rvalue_source_type rvalue_source_type;
+ typedef typename detail::shared_state<R>::move_dest_type move_dest_type;
+ typedef typename detail::shared_state<R>::shared_future_get_result_type shared_future_get_result_type;
+
+ future_ptr future_;
+ bool future_obtained;
+
+ void lazy_init()
+ {
+#if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
+#include <boost/detail/atomic_undef_macros.hpp>
+ if(!atomic_load(&future_))
+ {
+ future_ptr blank;
+ atomic_compare_exchange(&future_,&blank,future_ptr(new detail::shared_state<R>));
+ }
+#include <boost/detail/atomic_redef_macros.hpp>
+#endif
+ }
+
+ public:
+ BOOST_THREAD_MOVABLE_ONLY(promise)
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+ template <class Allocator>
+ promise(boost::allocator_arg_t, Allocator a)
+ {
+ typedef typename Allocator::template rebind<detail::shared_state<R> >::other A2;
+ A2 a2(a);
+ typedef thread_detail::allocator_destructor<A2> D;
+
+ future_ = future_ptr(::new(a2.allocate(1)) detail::shared_state<R>(), D(a2, 1) );
+ future_obtained = false;
+ }
+#endif
+ promise():
+#if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
+ future_(),
+#else
+ future_(new detail::shared_state<R>()),
+#endif
+ future_obtained(false)
+ {}
+
+ ~promise()
+ {
+ if(future_)
+ {
+ boost::unique_lock<boost::mutex> lock(future_->mutex);
+
+ if(!future_->done && !future_->is_constructed)
+ {
+ future_->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()), lock);
+ }
+ }
+ }
+
+ // Assignment
+ promise(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT :
+ future_(BOOST_THREAD_RV(rhs).future_),future_obtained(BOOST_THREAD_RV(rhs).future_obtained)
+ {
+ BOOST_THREAD_RV(rhs).future_.reset();
+ BOOST_THREAD_RV(rhs).future_obtained=false;
+ }
+ promise & operator=(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT
+ {
+ future_=BOOST_THREAD_RV(rhs).future_;
+ future_obtained=BOOST_THREAD_RV(rhs).future_obtained;
+ BOOST_THREAD_RV(rhs).future_.reset();
+ BOOST_THREAD_RV(rhs).future_obtained=false;
+ return *this;
+ }
+
+ void swap(promise& other)
+ {
+ future_.swap(other.future_);
+ std::swap(future_obtained,other.future_obtained);
+ }
+
+#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
+ void set_executor(executor_ptr_type aex)
+ {
+ lazy_init();
+ if (future_.get()==0)
+ {
+ boost::throw_exception(promise_moved());
+ }
+ boost::lock_guard<boost::mutex> lk(future_->mutex);
+ future_->set_executor_policy(aex, lk);
+ }
+#endif
+ // Result retrieval
+ BOOST_THREAD_FUTURE<R> get_future()
+ {
+ lazy_init();
+ if (future_.get()==0)
+ {
+ boost::throw_exception(promise_moved());
+ }
+ if (future_obtained)
+ {
+ boost::throw_exception(future_already_retrieved());
+ }
+ future_obtained=true;
+ return BOOST_THREAD_FUTURE<R>(future_);
+ }
+
+#if defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ template <class TR>
+ typename boost::enable_if_c<is_copy_constructible<TR>::value && is_same<R, TR>::value, void>::type set_value(TR const & r)
+ {
+ lazy_init();
+ boost::unique_lock<boost::mutex> lock(future_->mutex);
+ if(future_->done)
+ {
+ boost::throw_exception(promise_already_satisfied());
+ }
+ future_->mark_finished_with_result_internal(r, lock);
+ }
+#else
+ void set_value(source_reference_type r)
+ {
+ lazy_init();
+ boost::unique_lock<boost::mutex> lock(future_->mutex);
+ if(future_->done)
+ {
+ boost::throw_exception(promise_already_satisfied());
+ }
+ future_->mark_finished_with_result_internal(r, lock);
+ }
+#endif
+
+ void set_value(rvalue_source_type r)
+ {
+ lazy_init();
+ boost::unique_lock<boost::mutex> lock(future_->mutex);
+ if(future_->done)
+ {
+ boost::throw_exception(promise_already_satisfied());
+ }
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ future_->mark_finished_with_result_internal(boost::move(r), lock);
+#else
+ future_->mark_finished_with_result_internal(static_cast<rvalue_source_type>(r), lock);
+#endif
+ }
+
+#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template <class ...Args>
+ void emplace(BOOST_THREAD_FWD_REF(Args) ...args)
+ {
+ lazy_init();
+ boost::unique_lock<boost::mutex> lock(future_->mutex);
+ if(future_->done)
+ {
+ boost::throw_exception(promise_already_satisfied());
+ }
+ future_->mark_finished_with_result_internal(lock, boost::forward<Args>(args)...);
+ }
+
+#endif
+
+ void set_exception(boost::exception_ptr p)
+ {
+ lazy_init();
+ boost::unique_lock<boost::mutex> lock(future_->mutex);
+ if(future_->done)
+ {
+ boost::throw_exception(promise_already_satisfied());
+ }
+ future_->mark_exceptional_finish_internal(p, lock);
+ }
+ template <typename E>
+ void set_exception(E ex)
+ {
+ set_exception(boost::copy_exception(ex));
+ }
+ // setting the result with deferred notification
+#if defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ template <class TR>
+ typename boost::enable_if_c<is_copy_constructible<TR>::value && is_same<R, TR>::value, void>::type set_value_at_thread_exit(TR const& r)
+ {
+ if (future_.get()==0)
+ {
+ boost::throw_exception(promise_moved());
+ }
+ future_->set_value_at_thread_exit(r);
+ }
+#else
+ void set_value_at_thread_exit(source_reference_type r)
+ {
+ if (future_.get()==0)
+ {
+ boost::throw_exception(promise_moved());
+ }
+ future_->set_value_at_thread_exit(r);
+ }
+#endif
+ void set_value_at_thread_exit(BOOST_THREAD_RV_REF(R) r)
+ {
+ if (future_.get()==0)
+ {
+ boost::throw_exception(promise_moved());
+ }
+ future_->set_value_at_thread_exit(boost::move(r));
+ }
+ void set_exception_at_thread_exit(exception_ptr e)
+ {
+ if (future_.get()==0)
+ {
+ boost::throw_exception(promise_moved());
+ }
+ future_->set_exception_at_thread_exit(e);
+ }
+ template <typename E>
+ void set_exception_at_thread_exit(E ex)
+ {
+ set_exception_at_thread_exit(boost::copy_exception(ex));
+ }
+
+ template<typename F>
+ void set_wait_callback(F f)
+ {
+ lazy_init();
+ future_->set_wait_callback(f,this);
+ }
+
+ };
+
+ template <typename R>
+ class promise<R&>
+ {
+ typedef boost::shared_ptr<detail::shared_state<R&> > future_ptr;
+
+ future_ptr future_;
+ bool future_obtained;
+
+ void lazy_init()
+ {
+#if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
+#include <boost/detail/atomic_undef_macros.hpp>
+ if(!atomic_load(&future_))
+ {
+ future_ptr blank;
+ atomic_compare_exchange(&future_,&blank,future_ptr(new detail::shared_state<R&>));
+ }
+#include <boost/detail/atomic_redef_macros.hpp>
+#endif
+ }
+
+ public:
+ BOOST_THREAD_MOVABLE_ONLY(promise)
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+ template <class Allocator>
+ promise(boost::allocator_arg_t, Allocator a)
+ {
+ typedef typename Allocator::template rebind<detail::shared_state<R&> >::other A2;
+ A2 a2(a);
+ typedef thread_detail::allocator_destructor<A2> D;
+
+ future_ = future_ptr(::new(a2.allocate(1)) detail::shared_state<R&>(), D(a2, 1) );
+ future_obtained = false;
+ }
+#endif
+ promise():
+#if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
+ future_(),
+#else
+ future_(new detail::shared_state<R&>()),
+#endif
+ future_obtained(false)
+ {}
+
+ ~promise()
+ {
+ if(future_)
+ {
+ boost::unique_lock<boost::mutex> lock(future_->mutex);
+
+ if(!future_->done && !future_->is_constructed)
+ {
+ future_->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()), lock);
+ }
+ }
+ }
+
+ // Assignment
+ promise(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT :
+ future_(BOOST_THREAD_RV(rhs).future_),future_obtained(BOOST_THREAD_RV(rhs).future_obtained)
+ {
+ BOOST_THREAD_RV(rhs).future_.reset();
+ BOOST_THREAD_RV(rhs).future_obtained=false;
+ }
+ promise & operator=(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT
+ {
+ future_=BOOST_THREAD_RV(rhs).future_;
+ future_obtained=BOOST_THREAD_RV(rhs).future_obtained;
+ BOOST_THREAD_RV(rhs).future_.reset();
+ BOOST_THREAD_RV(rhs).future_obtained=false;
+ return *this;
+ }
+
+ void swap(promise& other)
+ {
+ future_.swap(other.future_);
+ std::swap(future_obtained,other.future_obtained);
+ }
+
+ // Result retrieval
+ BOOST_THREAD_FUTURE<R&> get_future()
+ {
+ lazy_init();
+ if (future_.get()==0)
+ {
+ boost::throw_exception(promise_moved());
+ }
+ if (future_obtained)
+ {
+ boost::throw_exception(future_already_retrieved());
+ }
+ future_obtained=true;
+ return BOOST_THREAD_FUTURE<R&>(future_);
+ }
+
+ void set_value(R& r)
+ {
+ lazy_init();
+ boost::unique_lock<boost::mutex> lock(future_->mutex);
+ if(future_->done)
+ {
+ boost::throw_exception(promise_already_satisfied());
+ }
+ future_->mark_finished_with_result_internal(r, lock);
+ }
+
+ void set_exception(boost::exception_ptr p)
+ {
+ lazy_init();
+ boost::unique_lock<boost::mutex> lock(future_->mutex);
+ if(future_->done)
+ {
+ boost::throw_exception(promise_already_satisfied());
+ }
+ future_->mark_exceptional_finish_internal(p, lock);
+ }
+ template <typename E>
+ void set_exception(E ex)
+ {
+ set_exception(boost::copy_exception(ex));
+ }
+
+ // setting the result with deferred notification
+ void set_value_at_thread_exit(R& r)
+ {
+ if (future_.get()==0)
+ {
+ boost::throw_exception(promise_moved());
+ }
+ future_->set_value_at_thread_exit(r);
+ }
+
+ void set_exception_at_thread_exit(exception_ptr e)
+ {
+ if (future_.get()==0)
+ {
+ boost::throw_exception(promise_moved());
+ }
+ future_->set_exception_at_thread_exit(e);
+ }
+ template <typename E>
+ void set_exception_at_thread_exit(E ex)
+ {
+ set_exception_at_thread_exit(boost::copy_exception(ex));
+ }
+
+ template<typename F>
+ void set_wait_callback(F f)
+ {
+ lazy_init();
+ future_->set_wait_callback(f,this);
+ }
+ };
+
+ template <>
+ class promise<void>
+ {
+ typedef boost::shared_ptr<detail::shared_state<void> > future_ptr;
+
+ future_ptr future_;
+ bool future_obtained;
+
+ void lazy_init()
+ {
+#if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
+ if(!atomic_load(&future_))
+ {
+ future_ptr blank;
+ atomic_compare_exchange(&future_,&blank,future_ptr(new detail::shared_state<void>));
+ }
+#endif
+ }
+ public:
+ BOOST_THREAD_MOVABLE_ONLY(promise)
+
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+ template <class Allocator>
+ promise(boost::allocator_arg_t, Allocator a)
+ {
+ typedef typename Allocator::template rebind<detail::shared_state<void> >::other A2;
+ A2 a2(a);
+ typedef thread_detail::allocator_destructor<A2> D;
+
+ future_ = future_ptr(::new(a2.allocate(1)) detail::shared_state<void>(), D(a2, 1) );
+ future_obtained = false;
+ }
+#endif
+ promise():
+#if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
+ future_(),
+#else
+ future_(new detail::shared_state<void>),
+#endif
+ future_obtained(false)
+ {}
+
+ ~promise()
+ {
+ if(future_)
+ {
+ boost::unique_lock<boost::mutex> lock(future_->mutex);
+
+ if(!future_->done && !future_->is_constructed)
+ {
+ future_->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()), lock);
+ }
+ }
+ }
+
+ // Assignment
+ promise(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT :
+ future_(BOOST_THREAD_RV(rhs).future_),future_obtained(BOOST_THREAD_RV(rhs).future_obtained)
+ {
+ // we need to release the future as shared_ptr doesn't implements move semantics
+ BOOST_THREAD_RV(rhs).future_.reset();
+ BOOST_THREAD_RV(rhs).future_obtained=false;
+ }
+
+ promise & operator=(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT
+ {
+ future_=BOOST_THREAD_RV(rhs).future_;
+ future_obtained=BOOST_THREAD_RV(rhs).future_obtained;
+ BOOST_THREAD_RV(rhs).future_.reset();
+ BOOST_THREAD_RV(rhs).future_obtained=false;
+ return *this;
+ }
+
+ void swap(promise& other)
+ {
+ future_.swap(other.future_);
+ std::swap(future_obtained,other.future_obtained);
+ }
+
+ // Result retrieval
+ BOOST_THREAD_FUTURE<void> get_future()
+ {
+ lazy_init();
+
+ if (future_.get()==0)
+ {
+ boost::throw_exception(promise_moved());
+ }
+ if(future_obtained)
+ {
+ boost::throw_exception(future_already_retrieved());
+ }
+ future_obtained=true;
+ //return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<void>(future_));
+ return BOOST_THREAD_FUTURE<void>(future_);
+ }
+
+ void set_value()
+ {
+ lazy_init();
+ boost::unique_lock<boost::mutex> lock(future_->mutex);
+ if(future_->done)
+ {
+ boost::throw_exception(promise_already_satisfied());
+ }
+ future_->mark_finished_with_result_internal(lock);
+ }
+
+ void set_exception(boost::exception_ptr p)
+ {
+ lazy_init();
+ boost::unique_lock<boost::mutex> lock(future_->mutex);
+ if(future_->done)
+ {
+ boost::throw_exception(promise_already_satisfied());
+ }
+ future_->mark_exceptional_finish_internal(p,lock);
+ }
+ template <typename E>
+ void set_exception(E ex)
+ {
+ set_exception(boost::copy_exception(ex));
+ }
+
+ // setting the result with deferred notification
+ void set_value_at_thread_exit()
+ {
+ if (future_.get()==0)
+ {
+ boost::throw_exception(promise_moved());
+ }
+ future_->set_value_at_thread_exit();
+ }
+
+ void set_exception_at_thread_exit(exception_ptr e)
+ {
+ if (future_.get()==0)
+ {
+ boost::throw_exception(promise_moved());
+ }
+ future_->set_exception_at_thread_exit(e);
+ }
+ template <typename E>
+ void set_exception_at_thread_exit(E ex)
+ {
+ set_exception_at_thread_exit(boost::copy_exception(ex));
+ }
+
+ template<typename F>
+ void set_wait_callback(F f)
+ {
+ lazy_init();
+ future_->set_wait_callback(f,this);
+ }
+
+ };
+}
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+namespace boost { namespace container {
+ template <class R, class Alloc>
+ struct uses_allocator< ::boost::promise<R> , Alloc> : true_type
+ {
+ };
+}}
+#if ! defined BOOST_NO_CXX11_ALLOCATOR
+namespace std {
+ template <class R, class Alloc>
+ struct uses_allocator< ::boost::promise<R> , Alloc> : true_type
+ {
+ };
+}
+#endif
+#endif
+
+namespace boost
+{
+
+ BOOST_THREAD_DCL_MOVABLE_BEG(T) promise<T> BOOST_THREAD_DCL_MOVABLE_END
+
+ namespace detail
+ {
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+ template<typename R>
+ struct task_base_shared_state;
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ template<typename R, typename ...ArgTypes>
+ struct task_base_shared_state<R(ArgTypes...)>:
+#else
+ template<typename R>
+ struct task_base_shared_state<R()>:
+#endif
+#else
+ template<typename R>
+ struct task_base_shared_state:
+#endif
+ detail::shared_state<R>
+ {
+ bool started;
+
+ task_base_shared_state():
+ started(false)
+ {}
+
+ void reset()
+ {
+ // todo The packaged_task::reset must be as if an assignemnt froma new packaged_task with the same function
+ // the reset function is an optimization that avoids reallocating a new task.
+ started=false;
+ this->validate();
+ }
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ virtual void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)=0;
+ void run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
+#else
+ virtual void do_run()=0;
+ void run()
+#endif
+ {
+ {
+ boost::lock_guard<boost::mutex> lk(this->mutex);
+ if(started)
+ {
+ boost::throw_exception(task_already_started());
+ }
+ started=true;
+ }
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ do_run(boost::move(args)...);
+#else
+ do_run();
+#endif
+ }
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ virtual void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)=0;
+ void apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
+#else
+ virtual void do_apply()=0;
+ void apply()
+#endif
+ {
+ {
+ boost::lock_guard<boost::mutex> lk(this->mutex);
+ if(started)
+ {
+ boost::throw_exception(task_already_started());
+ }
+ started=true;
+ }
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ do_apply(boost::move(args)...);
+#else
+ do_apply();
+#endif
+ }
+
+ void owner_destroyed()
+ {
+ boost::unique_lock<boost::mutex> lk(this->mutex);
+ if(!started)
+ {
+ started=true;
+ this->mark_exceptional_finish_internal(boost::copy_exception(boost::broken_promise()), lk);
+ }
+ }
+ };
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+ template<typename F, typename R>
+ struct task_shared_state;
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ template<typename F, typename R, typename ...ArgTypes>
+ struct task_shared_state<F, R(ArgTypes...)>:
+ task_base_shared_state<R(ArgTypes...)>
+#else
+ template<typename F, typename R>
+ struct task_shared_state<F, R()>:
+ task_base_shared_state<R()>
+#endif
+#else
+ template<typename F, typename R>
+ struct task_shared_state:
+ task_base_shared_state<R>
+#endif
+ {
+ private:
+ task_shared_state(task_shared_state&);
+ public:
+ F f;
+ task_shared_state(F const& f_):
+ f(f_)
+ {}
+ task_shared_state(BOOST_THREAD_RV_REF(F) f_):
+ f(boost::move(f_))
+ {}
+
+ F callable()
+ {
+ return boost::move(f);
+ }
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
+ {
+ try
+ {
+ this->set_value_at_thread_exit(f(boost::move(args)...));
+ }
+#else
+ void do_apply()
+ {
+ try
+ {
+ this->set_value_at_thread_exit(f());
+ }
+#endif
+ catch(...)
+ {
+ this->set_exception_at_thread_exit(current_exception());
+ }
+ }
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
+ {
+ try
+ {
+ this->mark_finished_with_result(f(boost::move(args)...));
+ }
+#else
+ void do_run()
+ {
+ try
+ {
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ R res((f()));
+ this->mark_finished_with_result(boost::move(res));
+#else
+ this->mark_finished_with_result(f());
+#endif
+ }
+#endif
+ catch(...)
+ {
+ this->mark_exceptional_finish();
+ }
+ }
+ };
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ template<typename F, typename R, typename ...ArgTypes>
+ struct task_shared_state<F, R&(ArgTypes...)>:
+ task_base_shared_state<R&(ArgTypes...)>
+#else
+ template<typename F, typename R>
+ struct task_shared_state<F, R&()>:
+ task_base_shared_state<R&()>
+#endif
+#else
+ template<typename F, typename R>
+ struct task_shared_state<F,R&>:
+ task_base_shared_state<R&>
+#endif
+ {
+ private:
+ task_shared_state(task_shared_state&);
+ public:
+ F f;
+ task_shared_state(F const& f_):
+ f(f_)
+ {}
+ task_shared_state(BOOST_THREAD_RV_REF(F) f_):
+ f(boost::move(f_))
+ {}
+
+ F callable()
+ {
+ return f;
+ }
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
+ {
+ try
+ {
+ this->set_value_at_thread_exit(f(boost::move(args)...));
+ }
+#else
+ void do_apply()
+ {
+ try
+ {
+ this->set_value_at_thread_exit(f());
+ }
+#endif
+ catch(...)
+ {
+ this->set_exception_at_thread_exit(current_exception());
+ }
+ }
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
+ {
+ try
+ {
+ this->mark_finished_with_result(f(boost::move(args)...));
+ }
+#else
+ void do_run()
+ {
+ try
+ {
+ R& res((f()));
+ this->mark_finished_with_result(res);
+ }
+#endif
+ catch(...)
+ {
+ this->mark_exceptional_finish();
+ }
+ }
+ };
+
+#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ template<typename R, typename ...ArgTypes>
+ struct task_shared_state<R (*)(ArgTypes...), R(ArgTypes...)>:
+ task_base_shared_state<R(ArgTypes...)>
+#else
+ template<typename R>
+ struct task_shared_state<R (*)(), R()>:
+ task_base_shared_state<R()>
+#endif
+#else
+ template<typename R>
+ struct task_shared_state<R (*)(), R> :
+ task_base_shared_state<R>
+#endif
+ {
+ private:
+ task_shared_state(task_shared_state&);
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ typedef R (*CallableType)(ArgTypes ... );
+#else
+ typedef R (*CallableType)();
+#endif
+ public:
+ CallableType f;
+ task_shared_state(CallableType f_):
+ f(f_)
+ {}
+
+ CallableType callable()
+ {
+ return f;
+ }
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
+ {
+ try
+ {
+ this->set_value_at_thread_exit(f(boost::move(args)...));
+ }
+#else
+ void do_apply()
+ {
+ try
+ {
+ R r((f()));
+ this->set_value_at_thread_exit(boost::move(r));
+ }
+#endif
+ catch(...)
+ {
+ this->set_exception_at_thread_exit(current_exception());
+ }
+ }
+
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
+ {
+ try
+ {
+ this->mark_finished_with_result(f(boost::move(args)...));
+ }
+#else
+ void do_run()
+ {
+ try
+ {
+ R res((f()));
+ this->mark_finished_with_result(boost::move(res));
+ }
+#endif
+ catch(...)
+ {
+ this->mark_exceptional_finish();
+ }
+ }
+ };
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ template<typename R, typename ...ArgTypes>
+ struct task_shared_state<R& (*)(ArgTypes...), R&(ArgTypes...)>:
+ task_base_shared_state<R&(ArgTypes...)>
+#else
+ template<typename R>
+ struct task_shared_state<R& (*)(), R&()>:
+ task_base_shared_state<R&()>
+#endif
+#else
+ template<typename R>
+ struct task_shared_state<R& (*)(), R&> :
+ task_base_shared_state<R&>
+#endif
+ {
+ private:
+ task_shared_state(task_shared_state&);
+ public:
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ typedef R& (*CallableType)(BOOST_THREAD_RV_REF(ArgTypes) ... );
+#else
+ typedef R& (*CallableType)();
+#endif
+ CallableType f;
+ task_shared_state(CallableType f_):
+ f(f_)
+ {}
+
+ CallableType callable()
+ {
+ return boost::move(f);
+ }
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
+ {
+ try
+ {
+ this->set_value_at_thread_exit(f(boost::move(args)...));
+ }
+#else
+ void do_apply()
+ {
+ try
+ {
+ this->set_value_at_thread_exit(f());
+ }
+#endif
+ catch(...)
+ {
+ this->set_exception_at_thread_exit(current_exception());
+ }
+ }
+
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
+ {
+ try
+ {
+ this->mark_finished_with_result(f(boost::move(args)...));
+ }
+#else
+ void do_run()
+ {
+ try
+ {
+ this->mark_finished_with_result(f());
+ }
+#endif
+ catch(...)
+ {
+ this->mark_exceptional_finish();
+ }
+ }
+ };
+#endif
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ template<typename F, typename ...ArgTypes>
+ struct task_shared_state<F, void(ArgTypes...)>:
+ task_base_shared_state<void(ArgTypes...)>
+#else
+ template<typename F>
+ struct task_shared_state<F, void()>:
+ task_base_shared_state<void()>
+#endif
+#else
+ template<typename F>
+ struct task_shared_state<F,void>:
+ task_base_shared_state<void>
+#endif
+ {
+ private:
+ task_shared_state(task_shared_state&);
+ public:
+ typedef F CallableType;
+ F f;
+ task_shared_state(F const& f_):
+ f(f_)
+ {}
+ task_shared_state(BOOST_THREAD_RV_REF(F) f_):
+ f(boost::move(f_))
+ {}
+ F callable()
+ {
+ return boost::move(f);
+ }
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
+ {
+ try
+ {
+ f(boost::move(args)...);
+#else
+ void do_apply()
+ {
+ try
+ {
+ f();
+#endif
+ this->set_value_at_thread_exit();
+ }
+ catch(...)
+ {
+ this->set_exception_at_thread_exit(current_exception());
+ }
+ }
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
+ {
+ try
+ {
+ f(boost::move(args)...);
+#else
+ void do_run()
+ {
+ try
+ {
+ f();
+#endif
+ this->mark_finished_with_result();
+ }
+ catch(...)
+ {
+ this->mark_exceptional_finish();
+ }
+ }
+ };
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ template<typename ...ArgTypes>
+ struct task_shared_state<void (*)(ArgTypes...), void(ArgTypes...)>:
+ task_base_shared_state<void(ArgTypes...)>
+#else
+ template<>
+ struct task_shared_state<void (*)(), void()>:
+ task_base_shared_state<void()>
+#endif
+#else
+ template<>
+ struct task_shared_state<void (*)(),void>:
+ task_base_shared_state<void>
+#endif
+ {
+ private:
+ task_shared_state(task_shared_state&);
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ typedef void (*CallableType)(ArgTypes...);
+#else
+ typedef void (*CallableType)();
+#endif
+ public:
+ CallableType f;
+ task_shared_state(CallableType f_):
+ f(f_)
+ {}
+ CallableType callable()
+ {
+ return f;
+ }
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
+ {
+ try
+ {
+ f(boost::move(args)...);
+#else
+ void do_apply()
+ {
+ try
+ {
+ f();
+#endif
+ this->set_value_at_thread_exit();
+ }
+ catch(...)
+ {
+ this->set_exception_at_thread_exit(current_exception());
+ }
+ }
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
+ {
+ try
+ {
+ f(boost::move(args)...);
+#else
+ void do_run()
+ {
+ try
+ {
+ f();
+#endif
+ this->mark_finished_with_result();
+ }
+ catch(...)
+ {
+ this->mark_exceptional_finish();
+ }
+ }
+ };
+ }
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+ #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ template<typename R, typename ...ArgTypes>
+ class packaged_task<R(ArgTypes...)>
+ {
+ typedef boost::shared_ptr<detail::task_base_shared_state<R(ArgTypes...)> > task_ptr;
+ boost::shared_ptr<detail::task_base_shared_state<R(ArgTypes...)> > task;
+ #else
+ template<typename R>
+ class packaged_task<R()>
+ {
+ typedef boost::shared_ptr<detail::task_base_shared_state<R()> > task_ptr;
+ boost::shared_ptr<detail::task_base_shared_state<R()> > task;
+ #endif
+#else
+ template<typename R>
+ class packaged_task
+ {
+ typedef boost::shared_ptr<detail::task_base_shared_state<R> > task_ptr;
+ boost::shared_ptr<detail::task_base_shared_state<R> > task;
+#endif
+ bool future_obtained;
+ struct dummy;
+
+ public:
+ typedef R result_type;
+ BOOST_THREAD_MOVABLE_ONLY(packaged_task)
+
+ packaged_task():
+ future_obtained(false)
+ {}
+
+ // construction and destruction
+#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+ #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ explicit packaged_task(R(*f)(), BOOST_THREAD_FWD_REF(ArgTypes)... args)
+ {
+ typedef R(*FR)(BOOST_THREAD_FWD_REF(ArgTypes)...);
+ typedef detail::task_shared_state<FR,R(ArgTypes...)> task_shared_state_type;
+ task= task_ptr(new task_shared_state_type(f, boost::move(args)...));
+ future_obtained=false;
+ }
+ #else
+ explicit packaged_task(R(*f)())
+ {
+ typedef R(*FR)();
+ typedef detail::task_shared_state<FR,R()> task_shared_state_type;
+ task= task_ptr(new task_shared_state_type(f));
+ future_obtained=false;
+ }
+ #endif
+#else
+ explicit packaged_task(R(*f)())
+ {
+ typedef R(*FR)();
+ typedef detail::task_shared_state<FR,R> task_shared_state_type;
+ task= task_ptr(new task_shared_state_type(f));
+ future_obtained=false;
+ }
+#endif
+#endif
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ template <class F>
+ explicit packaged_task(BOOST_THREAD_FWD_REF(F) f
+ , typename boost::disable_if<is_same<typename decay<F>::type, packaged_task>, dummy* >::type=0
+ )
+ {
+ typedef typename decay<F>::type FR;
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+ #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ typedef detail::task_shared_state<FR,R(ArgTypes...)> task_shared_state_type;
+ #else
+ typedef detail::task_shared_state<FR,R()> task_shared_state_type;
+ #endif
+#else
+ typedef detail::task_shared_state<FR,R> task_shared_state_type;
+#endif
+ task = task_ptr(new task_shared_state_type(boost::forward<F>(f)));
+ future_obtained = false;
+
+ }
+
+#else
+ template <class F>
+ explicit packaged_task(F const& f
+ , typename boost::disable_if<is_same<typename decay<F>::type, packaged_task>, dummy* >::type=0
+ )
+ {
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+ #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ typedef detail::task_shared_state<F,R(ArgTypes...)> task_shared_state_type;
+ #else
+ typedef detail::task_shared_state<F,R()> task_shared_state_type;
+ #endif
+#else
+ typedef detail::task_shared_state<F,R> task_shared_state_type;
+#endif
+ task = task_ptr(new task_shared_state_type(f));
+ future_obtained=false;
+ }
+ template <class F>
+ explicit packaged_task(BOOST_THREAD_RV_REF(F) f)
+ {
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ typedef detail::task_shared_state<F,R(ArgTypes...)> task_shared_state_type;
+ task = task_ptr(new task_shared_state_type(boost::move(f)));
+#else
+ typedef detail::task_shared_state<F,R()> task_shared_state_type;
+ task = task_ptr(new task_shared_state_type(boost::move(f)));
+#endif
+#else
+ typedef detail::task_shared_state<F,R> task_shared_state_type;
+ task = task_ptr(new task_shared_state_type(boost::move(f)));
+#endif
+ future_obtained=false;
+
+ }
+#endif
+
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
+ template <class Allocator>
+ packaged_task(boost::allocator_arg_t, Allocator a, R(*f)())
+ {
+ typedef R(*FR)();
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+ #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ typedef detail::task_shared_state<FR,R(ArgTypes...)> task_shared_state_type;
+ #else
+ typedef detail::task_shared_state<FR,R()> task_shared_state_type;
+ #endif
+#else
+ typedef detail::task_shared_state<FR,R> task_shared_state_type;
+#endif
+ typedef typename Allocator::template rebind<task_shared_state_type>::other A2;
+ A2 a2(a);
+ typedef thread_detail::allocator_destructor<A2> D;
+
+ task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(f), D(a2, 1) );
+ future_obtained = false;
+ }
+#endif // BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
+
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ template <class F, class Allocator>
+ packaged_task(boost::allocator_arg_t, Allocator a, BOOST_THREAD_FWD_REF(F) f)
+ {
+ typedef typename decay<F>::type FR;
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+ #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ typedef detail::task_shared_state<FR,R(ArgTypes...)> task_shared_state_type;
+ #else
+ typedef detail::task_shared_state<FR,R()> task_shared_state_type;
+ #endif
+#else
+ typedef detail::task_shared_state<FR,R> task_shared_state_type;
+#endif
+ typedef typename Allocator::template rebind<task_shared_state_type>::other A2;
+ A2 a2(a);
+ typedef thread_detail::allocator_destructor<A2> D;
+
+ task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(boost::forward<F>(f)), D(a2, 1) );
+ future_obtained = false;
+ }
+#else // ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ template <class F, class Allocator>
+ packaged_task(boost::allocator_arg_t, Allocator a, const F& f)
+ {
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+ #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ typedef detail::task_shared_state<F,R(ArgTypes...)> task_shared_state_type;
+ #else
+ typedef detail::task_shared_state<F,R()> task_shared_state_type;
+ #endif
+#else
+ typedef detail::task_shared_state<F,R> task_shared_state_type;
+#endif
+ typedef typename Allocator::template rebind<task_shared_state_type>::other A2;
+ A2 a2(a);
+ typedef thread_detail::allocator_destructor<A2> D;
+
+ task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(f), D(a2, 1) );
+ future_obtained = false;
+ }
+ template <class F, class Allocator>
+ packaged_task(boost::allocator_arg_t, Allocator a, BOOST_THREAD_RV_REF(F) f)
+ {
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+ #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ typedef detail::task_shared_state<F,R(ArgTypes...)> task_shared_state_type;
+ #else
+ typedef detail::task_shared_state<F,R()> task_shared_state_type;
+ #endif
+#else
+ typedef detail::task_shared_state<F,R> task_shared_state_type;
+#endif
+ typedef typename Allocator::template rebind<task_shared_state_type>::other A2;
+ A2 a2(a);
+ typedef thread_detail::allocator_destructor<A2> D;
+
+ task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(boost::move(f)), D(a2, 1) );
+ future_obtained = false;
+ }
+
+#endif //BOOST_NO_CXX11_RVALUE_REFERENCES
+#endif // BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+
+ ~packaged_task() {
+ if(task) {
+ task->owner_destroyed();
+ }
+ }
+
+ // assignment
+ packaged_task(BOOST_THREAD_RV_REF(packaged_task) other) BOOST_NOEXCEPT
+ : future_obtained(BOOST_THREAD_RV(other).future_obtained) {
+ task.swap(BOOST_THREAD_RV(other).task);
+ BOOST_THREAD_RV(other).future_obtained=false;
+ }
+ packaged_task& operator=(BOOST_THREAD_RV_REF(packaged_task) other) BOOST_NOEXCEPT {
+
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ packaged_task temp(boost::move(other));
+#else
+ packaged_task temp(static_cast<BOOST_THREAD_RV_REF(packaged_task)>(other));
+#endif
+ swap(temp);
+ return *this;
+ }
+
+#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
+ void set_executor(executor_ptr_type aex)
+ {
+ if (!valid())
+ boost::throw_exception(task_moved());
+ boost::lock_guard<boost::mutex> lk(task->mutex);
+ task->set_executor_policy(aex, lk);
+ }
+#endif
+ void reset() {
+ if (!valid())
+ boost::throw_exception(future_error(system::make_error_code(future_errc::no_state)));
+
+ // As if *this = packaged_task(task->callable());
+
+ task->reset();
+ future_obtained=false;
+ }
+
+ void swap(packaged_task& other) BOOST_NOEXCEPT {
+ task.swap(other.task);
+ std::swap(future_obtained,other.future_obtained);
+ }
+ bool valid() const BOOST_NOEXCEPT {
+ return task.get()!=0;
+ }
+
+ // result retrieval
+ BOOST_THREAD_FUTURE<R> get_future() {
+ if(!task) {
+ boost::throw_exception(task_moved());
+ } else if(!future_obtained) {
+ future_obtained=true;
+ return BOOST_THREAD_FUTURE<R>(task);
+ } else {
+ boost::throw_exception(future_already_retrieved());
+ }
+ }
+
+ // execution
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ void operator()(ArgTypes... args) {
+ if(!task) {
+ boost::throw_exception(task_moved());
+ }
+ task->run(boost::move(args)...);
+ }
+ void make_ready_at_thread_exit(ArgTypes... args) {
+ if(!task) {
+ boost::throw_exception(task_moved());
+ }
+ if (task->has_value()) {
+ boost::throw_exception(promise_already_satisfied());
+ }
+ task->apply(boost::move(args)...);
+ }
+#else
+ void operator()() {
+ if(!task) {
+ boost::throw_exception(task_moved());
+ }
+ task->run();
+ }
+ void make_ready_at_thread_exit() {
+ if(!task) {
+ boost::throw_exception(task_moved());
+ }
+ if (task->has_value()) boost::throw_exception(promise_already_satisfied());
+ task->apply();
+ }
+#endif
+ template<typename F>
+ void set_wait_callback(F f) {
+ task->set_wait_callback(f,this);
+ }
+ };
+}
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+namespace boost { namespace container {
+ template <class R, class Alloc>
+ struct uses_allocator< ::boost::packaged_task<R> , Alloc> : true_type
+ {};
+}}
+#if ! defined BOOST_NO_CXX11_ALLOCATOR
+namespace std {
+ template <class R, class Alloc>
+ struct uses_allocator< ::boost::packaged_task<R> , Alloc> : true_type
+ {};
+}
+#endif
+#endif
+
+namespace boost
+{
+ BOOST_THREAD_DCL_MOVABLE_BEG(T) packaged_task<T> BOOST_THREAD_DCL_MOVABLE_END
+
+namespace detail
+{
+ ////////////////////////////////
+ // make_future_deferred_shared_state
+ ////////////////////////////////
+ template <class Rp, class Fp>
+ BOOST_THREAD_FUTURE<Rp>
+ make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f) {
+ shared_ptr<future_deferred_shared_state<Rp, Fp> >
+ h(new future_deferred_shared_state<Rp, Fp>(boost::forward<Fp>(f)));
+ return BOOST_THREAD_FUTURE<Rp>(h);
+ }
+
+ ////////////////////////////////
+ // make_future_async_shared_state
+ ////////////////////////////////
+ template <class Rp, class Fp>
+ BOOST_THREAD_FUTURE<Rp>
+ make_future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f) {
+ shared_ptr<future_async_shared_state<Rp, Fp> >
+ h(new future_async_shared_state<Rp, Fp>());
+ h->init(boost::forward<Fp>(f));
+ return BOOST_THREAD_FUTURE<Rp>(h);
+ }
+}
+
+ ////////////////////////////////
+ // template <class F, class... ArgTypes>
+ // future<R> async(launch policy, F&&, ArgTypes&&...);
+ ////////////////////////////////
+
+#if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
+
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ template <class R, class... ArgTypes>
+ BOOST_THREAD_FUTURE<R>
+ async(launch policy, R(*f)(BOOST_THREAD_FWD_REF(ArgTypes)...), BOOST_THREAD_FWD_REF(ArgTypes)... args) {
+ typedef R(*F)(BOOST_THREAD_FWD_REF(ArgTypes)...);
+ typedef detail::invoker<typename decay<F>::type, typename decay<ArgTypes>::type...> BF;
+ typedef typename BF::result_type Rp;
+
+ if (underlying_cast<int>(policy) & int(launch::async)) {
+ return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_async_shared_state<Rp>(
+ BF(
+ f
+ , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
+ )
+ ));
+ } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
+ return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_deferred_shared_state<Rp>(
+ BF(
+ f
+ , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
+ )
+ ));
+ } else {
+ std::terminate();
+ //BOOST_THREAD_FUTURE<R> ret;
+ //return ::boost::move(ret);
+ }
+ }
+
+#else // defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+
+ template <class R>
+ BOOST_THREAD_FUTURE<R>
+ async(launch policy, R(*f)()) {
+ #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+ typedef packaged_task<R()> packaged_task_type;
+ #else
+ typedef packaged_task<R> packaged_task_type;
+ #endif
+
+ if (underlying_cast<int>(policy) & int(launch::async)) {
+ packaged_task_type pt( f );
+ BOOST_THREAD_FUTURE<R> ret = BOOST_THREAD_MAKE_RV_REF(pt.get_future());
+ ret.set_async();
+ boost::thread( boost::move(pt) ).detach();
+ return ::boost::move(ret);
+ } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
+ std::terminate();
+ //BOOST_THREAD_FUTURE<R> ret;
+ //return ::boost::move(ret);
+ } else {
+ std::terminate();
+ //BOOST_THREAD_FUTURE<R> ret;
+ //return ::boost::move(ret);
+ }
+ }
+#endif
+#endif // defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
+
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+
+ template <class F, class ...ArgTypes>
+ BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
+ typename decay<ArgTypes>::type...
+ )>::type>
+ async(launch policy, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(ArgTypes)... args) {
+ typedef detail::invoker<typename decay<F>::type, typename decay<ArgTypes>::type...> BF;
+ typedef typename BF::result_type Rp;
+
+ if (underlying_cast<int>(policy) & int(launch::async)) {
+ return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_async_shared_state<Rp>(
+ BF(
+ thread_detail::decay_copy(boost::forward<F>(f))
+ , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
+ )
+ ));
+ } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
+ return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_deferred_shared_state<Rp>(
+ BF(
+ thread_detail::decay_copy(boost::forward<F>(f))
+ , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
+ )
+ ));
+ } else {
+ std::terminate();
+ //BOOST_THREAD_FUTURE<R> ret;
+ //return ::boost::move(ret);
+ }
+ }
+
+#else // defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+
+ template <class F>
+ BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type()>::type>
+ async(launch policy, BOOST_THREAD_FWD_REF(F) f) {
+ typedef typename boost::result_of<typename decay<F>::type()>::type R;
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+ typedef packaged_task<R()> packaged_task_type;
+#else // defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+ typedef packaged_task<R> packaged_task_type;
+#endif // defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+
+ if (underlying_cast<int>(policy) & int(launch::async)) {
+ packaged_task_type pt( boost::forward<F>(f) );
+ BOOST_THREAD_FUTURE<R> ret = pt.get_future();
+ ret.set_async();
+ boost::thread( boost::move(pt) ).detach();
+ return ::boost::move(ret);
+ } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
+ std::terminate();
+ //BOOST_THREAD_FUTURE<R> ret;
+ //return ::boost::move(ret);
+ // return boost::detail::make_future_deferred_shared_state<Rp>(
+ // BF(
+ // thread_detail::decay_copy(boost::forward<F>(f))
+ // )
+ // );
+ } else {
+ std::terminate();
+ //BOOST_THREAD_FUTURE<R> ret;
+ //return ::boost::move(ret);
+ }
+ }
+#endif // defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+
+#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
+namespace detail {
+
+ /////////////////////////
+ /// shared_state_nullary_task
+ /////////////////////////
+ template<typename Rp, typename Fp>
+ struct shared_state_nullary_task
+ {
+
+ typedef shared_ptr<shared_state_base > storage_type;
+ storage_type that;
+ Fp f_;
+ public:
+
+ shared_state_nullary_task(storage_type st, BOOST_THREAD_FWD_REF(Fp) f)
+ : that(st), f_(boost::move(f))
+ {};
+
+#if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ BOOST_THREAD_COPYABLE_AND_MOVABLE(shared_state_nullary_task)
+ shared_state_nullary_task(shared_state_nullary_task const& x) //BOOST_NOEXCEPT
+ : that(x.that), f_(x.f_)
+ {}
+ shared_state_nullary_task& operator=(BOOST_THREAD_COPY_ASSIGN_REF(shared_state_nullary_task) x) //BOOST_NOEXCEPT
+ {
+ if (this != &x) {
+ that=x.that;
+ f_=x.f_;
+ }
+ return *this;
+ }
+ // move
+ shared_state_nullary_task(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) //BOOST_NOEXCEPT
+ : that(x.that), f_(boost::move(x.f_))
+ {
+ x.that.reset();
+ }
+ shared_state_nullary_task& operator=(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) //BOOST_NOEXCEPT
+ {
+ if (this != &x) {
+ that=x.that;
+ f_=boost::move(x.f_);
+ x.that.reset();
+ }
+ return *this;
+ }
+#endif
+ void operator()() {
+ shared_ptr<shared_state<Rp> > that_ = static_pointer_cast<shared_state<Rp> >(that);
+ try {
+ that_->mark_finished_with_result(f_());
+ } catch(...) {
+ that_->mark_exceptional_finish();
+ }
+ }
+ ~shared_state_nullary_task()
+ {
+ }
+ };
+
+ template<typename Fp>
+ struct shared_state_nullary_task<void, Fp>
+ {
+ typedef shared_ptr<shared_state_base > storage_type;
+ storage_type that;
+ Fp f_;
+ public:
+ shared_state_nullary_task(storage_type st, BOOST_THREAD_FWD_REF(Fp) f)
+ : that(st), f_(boost::move(f))
+ {};
+
+#if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ BOOST_THREAD_COPYABLE_AND_MOVABLE(shared_state_nullary_task)
+ shared_state_nullary_task(shared_state_nullary_task const& x) //BOOST_NOEXCEPT
+ : that(x.that), f_(x.f_)
+ {}
+ shared_state_nullary_task& operator=(BOOST_THREAD_COPY_ASSIGN_REF(shared_state_nullary_task) x) //BOOST_NOEXCEPT
+ {
+ if (this != &x) {
+ that=x.that;
+ f_=x.f_;
+ }
+ return *this;
+ }
+ // move
+ shared_state_nullary_task(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) BOOST_NOEXCEPT
+ : that(x.that), f_(boost::move(x.f_))
+ {
+ x.that.reset();
+ }
+ shared_state_nullary_task& operator=(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) BOOST_NOEXCEPT {
+ if (this != &x) {
+ that=x.that;
+ f_=boost::move(x.f_);
+ x.that.reset();
+ }
+ return *this;
+ }
+#endif
+ void operator()() {
+ shared_ptr<shared_state<void> > that_ = static_pointer_cast<shared_state<void> >(that);
+ try {
+ f_();
+ that_->mark_finished_with_result();
+ } catch(...) {
+ that_->mark_exceptional_finish();
+ }
+ }
+ };
+
+}
+ BOOST_THREAD_DCL_MOVABLE_BEG2(R,F) detail::shared_state_nullary_task<R,F> BOOST_THREAD_DCL_MOVABLE_END
+namespace detail {
+
+ /////////////////////////
+ /// future_executor_shared_state_base
+ /////////////////////////
+ template<typename Rp>
+ struct future_executor_shared_state: shared_state<Rp>
+ {
+ typedef shared_state<Rp> base_type;
+ protected:
+ public:
+ future_executor_shared_state() {
+ }
+
+ template <class Fp, class Executor>
+ void init(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f)
+ {
+ typedef typename decay<Fp>::type Cont;
+ this->set_executor_policy(executor_ptr_type(new executor_ref<Executor>(ex)));
+ shared_state_nullary_task<Rp,Cont> t(this->shared_from_this(), boost::forward<Fp>(f));
+ ex.submit(boost::move(t));
+ }
+
+ ~future_executor_shared_state() {}
+ };
+
+ ////////////////////////////////
+ // make_future_executor_shared_state
+ ////////////////////////////////
+ template <class Rp, class Fp, class Executor>
+ BOOST_THREAD_FUTURE<Rp>
+ make_future_executor_shared_state(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f) {
+ shared_ptr<future_executor_shared_state<Rp> >
+ h(new future_executor_shared_state<Rp>());
+ h->init(ex, boost::forward<Fp>(f));
+ return BOOST_THREAD_FUTURE<Rp>(h);
+ }
+
+} // detail
+
+ ////////////////////////////////
+ // template <class Executor, class F, class... ArgTypes>
+ // future<R> async(Executor& ex, F&&, ArgTypes&&...);
+ ////////////////////////////////
+
+//#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#if defined(BOOST_THREAD_PROVIDES_INVOKE) && ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && ! defined(BOOST_NO_CXX11_HDR_TUPLE)
+
+#if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
+
+ template <class Executor, class R, class... ArgTypes>
+ BOOST_THREAD_FUTURE<R>
+ async(Executor& ex, R(*f)(BOOST_THREAD_FWD_REF(ArgTypes)...), BOOST_THREAD_FWD_REF(ArgTypes)... args) {
+ typedef R(*F)(BOOST_THREAD_FWD_REF(ArgTypes)...);
+ typedef detail::invoker<typename decay<F>::type, typename decay<ArgTypes>::type...> BF;
+ typedef typename BF::result_type Rp;
+
+ return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
+ BF(
+ f
+ , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
+ )
+ ));
+ }
+#endif // defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
+
+ template <class Executor, class F, class ...ArgTypes>
+ BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
+ typename decay<ArgTypes>::type...
+ )>::type>
+ async(Executor& ex, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(ArgTypes)... args) {
+ typedef detail::invoker<typename decay<F>::type, typename decay<ArgTypes>::type...> BF;
+ typedef typename BF::result_type Rp;
+
+ return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
+ BF(
+ thread_detail::decay_copy(boost::forward<F>(f))
+ , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
+ )
+ ));
+ }
+
+#else // ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
+
+ template <class Executor, class R>
+ BOOST_THREAD_FUTURE<R>
+ async(Executor& ex, R(*f)()) {
+ typedef R(*F)();
+ typedef detail::invoker<F> BF;
+ typedef typename BF::result_type Rp;
+
+ return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
+ BF(
+ f
+ )
+ ));
+ }
+
+ template <class Executor, class R, class A1>
+ BOOST_THREAD_FUTURE<R>
+ async(Executor& ex, R(*f)(BOOST_THREAD_FWD_REF(A1)), BOOST_THREAD_FWD_REF(A1) a1) {
+ typedef R(*F)(BOOST_THREAD_FWD_REF(A1));
+ typedef detail::invoker<F, typename decay<A1>::type> BF;
+ typedef typename BF::result_type Rp;
+
+ return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
+ BF(
+ f
+ , thread_detail::decay_copy(boost::forward<A1>(a1))
+ )
+ ));
+ }
+#endif // defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
+
+ template <class Executor, class F>
+ BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type()>::type>
+ async(Executor& ex, BOOST_THREAD_FWD_REF(F) f) {
+ typedef detail::invoker<typename decay<F>::type> BF;
+ typedef typename BF::result_type Rp;
+
+ return boost::detail::make_future_executor_shared_state<Rp>(ex,
+ BF(
+ thread_detail::decay_copy(boost::forward<F>(f))
+ )
+ );
+ }
+
+ template <class Executor, class F, class A1>
+ BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
+ typename decay<A1>::type
+ )>::type>
+ async(Executor& ex, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1) {
+ typedef detail::invoker<typename decay<F>::type, typename decay<A1>::type> BF;
+ typedef typename BF::result_type Rp;
+
+ return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
+ BF(
+ thread_detail::decay_copy(boost::forward<F>(f))
+ , thread_detail::decay_copy(boost::forward<A1>(a1))
+ )
+ ));
+ }
+
+ template <class Executor, class F, class A1, class A2>
+ BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
+ typename decay<A1>::type, typename decay<A2>::type
+ )>::type>
+ async(Executor& ex, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1, BOOST_THREAD_FWD_REF(A2) a2) {
+ typedef detail::invoker<typename decay<F>::type, typename decay<A1>::type, typename decay<A2>::type> BF;
+ typedef typename BF::result_type Rp;
+
+ return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
+ BF(
+ thread_detail::decay_copy(boost::forward<F>(f))
+ , thread_detail::decay_copy(boost::forward<A1>(a1))
+ , thread_detail::decay_copy(boost::forward<A2>(a2))
+ )
+ ));
+ }
+
+#endif //! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#endif
+
+ ////////////////////////////////
+ // template <class F, class... ArgTypes>
+ // future<R> async(F&&, ArgTypes&&...);
+ ////////////////////////////////
+
+#if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
+ #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ template <class R, class... ArgTypes>
+ BOOST_THREAD_FUTURE<R>
+ async(R(*f)(BOOST_THREAD_FWD_REF(ArgTypes)...), BOOST_THREAD_FWD_REF(ArgTypes)... args) {
+ return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), f, boost::forward<ArgTypes>(args)...));
+ }
+ #else
+ template <class R>
+ BOOST_THREAD_FUTURE<R>
+ async(R(*f)()) {
+ return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), f));
+ }
+ #endif
+#endif
+
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ template <class F, class ...ArgTypes>
+ BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
+ typename decay<ArgTypes>::type...
+ )>::type>
+ async(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(ArgTypes)... args) {
+ return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), boost::forward<F>(f), boost::forward<ArgTypes>(args)...));
+ }
+#else
+ template <class F>
+ BOOST_THREAD_FUTURE<typename boost::result_of<F()>::type>
+ async(BOOST_THREAD_FWD_REF(F) f) {
+ return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), boost::forward<F>(f)));
+ }
+#endif
+
+ ////////////////////////////////
+ // make_future deprecated
+ ////////////////////////////////
+ template <typename T>
+ BOOST_THREAD_FUTURE<typename decay<T>::type> make_future(BOOST_THREAD_FWD_REF(T) value) {
+ typedef typename decay<T>::type future_value_type;
+ promise<future_value_type> p;
+ p.set_value(boost::forward<future_value_type>(value));
+ return BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ }
+
+#if defined BOOST_THREAD_USES_MOVE
+ inline BOOST_THREAD_FUTURE<void> make_future() {
+ promise<void> p;
+ p.set_value();
+ return BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ }
+#endif
+
+ ////////////////////////////////
+ // make_ready_future
+ ////////////////////////////////
+ namespace detail {
+ template <class T>
+ struct deduced_type_impl
+ {
+ typedef T type;
+ };
+
+ template <class T>
+ struct deduced_type_impl<reference_wrapper<T> const>
+ {
+ typedef T& type;
+ };
+ template <class T>
+ struct deduced_type_impl<reference_wrapper<T> >
+ {
+ typedef T& type;
+ };
+#if __cplusplus > 201103L
+ template <class T>
+ struct deduced_type_impl<std::reference_wrapper<T> >
+ {
+ typedef T& type;
+ };
+#endif
+ template <class T>
+ struct deduced_type
+ {
+ typedef typename detail::deduced_type_impl<typename decay<T>::type>::type type;
+ };
+
+ }
+
+
+#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template <int = 0, int..., class T>
+#else
+ template <class T>
+#endif
+ BOOST_THREAD_FUTURE<typename detail::deduced_type<T>::type> make_ready_future(BOOST_THREAD_FWD_REF(T) value) {
+ typedef typename detail::deduced_type<T>::type future_value_type;
+ promise<future_value_type> p;
+ p.set_value(boost::forward<T>(value));
+ return BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ }
+
+ // explicit overloads
+ template <class T>
+ BOOST_THREAD_FUTURE<T> make_ready_future(typename remove_reference<T>::type & x)
+ {
+ promise<T> p;
+ p.set_value(x);
+ return p.get_future();
+ }
+
+ template <class T>
+ BOOST_THREAD_FUTURE<T> make_ready_future(BOOST_THREAD_FWD_REF(typename remove_reference<T>::type) x)
+ {
+ promise<T> p;
+ p.set_value(forward<typename remove_reference<T>::type>(x));
+ return p.get_future();
+ }
+
+ // variadic overload
+#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template <class T, class ...Args>
+ BOOST_THREAD_FUTURE<T> make_ready_future(Args&&... args)
+ {
+ promise<T> p;
+ p.emplace(forward<Args>(args)...);
+ return p.get_future();
+
+ }
+#endif
+
+ template <typename T, typename T1>
+ BOOST_THREAD_FUTURE<T> make_ready_no_decay_future(T1 value) {
+ typedef T future_value_type;
+ promise<future_value_type> p;
+ p.set_value(value);
+ return BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ }
+
+#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined BOOST_THREAD_USES_MOVE
+ inline BOOST_THREAD_FUTURE<void> make_ready_future() {
+ promise<void> p;
+ p.set_value();
+ return p.get_future();
+ }
+#endif
+
+
+ template <typename T>
+ BOOST_THREAD_FUTURE<T> make_exceptional_future(exception_ptr ex) {
+ promise<T> p;
+ p.set_exception(ex);
+ return BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ }
+
+ template <typename T, typename E>
+ BOOST_THREAD_FUTURE<T> make_exceptional_future(E ex) {
+ promise<T> p;
+ p.set_exception(boost::copy_exception(ex));
+ return BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ }
+
+ template <typename T>
+ BOOST_THREAD_FUTURE<T> make_exceptional_future() {
+ promise<T> p;
+ p.set_exception(boost::current_exception());
+ return BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ }
+ template <typename T>
+ BOOST_THREAD_FUTURE<T> make_ready_future(exception_ptr ex) {
+ return make_exceptional_future<T>(ex);
+ }
+
+#if 0
+ template<typename CLOSURE>
+ make_future(CLOSURE closure) -> BOOST_THREAD_FUTURE<decltype(closure())> {
+ typedef decltype(closure()) T;
+ promise<T> p;
+ try {
+ p.set_value(closure());
+ } catch(...) {
+ p.set_exception(std::current_exception());
+ }
+ return BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ }
+#endif
+
+ ////////////////////////////////
+ // make_shared_future deprecated
+ ////////////////////////////////
+ template <typename T>
+ shared_future<typename decay<T>::type> make_shared_future(BOOST_THREAD_FWD_REF(T) value) {
+ typedef typename decay<T>::type future_type;
+ promise<future_type> p;
+ p.set_value(boost::forward<T>(value));
+ return BOOST_THREAD_MAKE_RV_REF(p.get_future().share());
+ }
+
+ inline shared_future<void> make_shared_future() {
+ promise<void> p;
+ return BOOST_THREAD_MAKE_RV_REF(p.get_future().share());
+ }
+
+ ////////////////////////////////
+ // detail::future_async_continuation_shared_state
+ ////////////////////////////////
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
+
+#if defined BOOST_THREAD_CONTINUATION_SYNC
+#define continuation_shared_state_base shared_state
+#else
+#define continuation_shared_state_base future_async_shared_state_base
+#endif
+
+namespace detail
+{
+ //////////////////////
+ // detail::continuation_shared_state
+ //////////////////////
+ template<typename F, typename Rp, typename Fp, class ShSt=shared_state<Rp> >
+ struct continuation_shared_state: ShSt
+ {
+ F parent;
+ Fp continuation;
+
+ public:
+ continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
+ : parent(boost::move(f)),
+ continuation(boost::move(c))
+ {
+ }
+
+ void init(boost::unique_lock<boost::mutex> &lock)
+ {
+ parent.future_->set_continuation_ptr(this->shared_from_this(), lock);
+ }
+
+ void call() {
+ try {
+ this->mark_finished_with_result(this->continuation(boost::move(this->parent)));
+ } catch(...) {
+ this->mark_exceptional_finish();
+ }
+ // make sure parent is really cleared to prevent memory "leaks"
+ this->parent = F();
+ }
+
+ void call(boost::unique_lock<boost::mutex>& lck) {
+ try {
+ relocker relock(lck);
+
+ // neither continuation nor parent are protected by the lock - call() must only
+ // be called once, and no one else must modify it.
+ Rp res = this->continuation(boost::move(this->parent));
+
+ // make sure parent is really cleared to prevent memory "leaks"
+ this->parent = F();
+
+ relock.lock();
+
+ this->mark_finished_with_result_internal(boost::move(res), lck);
+ } catch (...) {
+ this->mark_exceptional_finish_internal(current_exception(), lck);
+
+ // make sure parent is really cleared to prevent memory "leaks"
+ relocker relock(lck);
+ this->parent = F();
+ }
+ }
+
+ static void run(shared_ptr<boost::detail::shared_state_base> that_)
+ {
+ continuation_shared_state* that = static_cast<continuation_shared_state*>(that_.get());
+ that->call();
+ }
+
+ ~continuation_shared_state() {}
+ };
+
+ template<typename F, typename Fp, class ShSt>
+ struct continuation_shared_state<F, void, Fp, ShSt>: ShSt
+ {
+ F parent;
+ Fp continuation;
+
+ public:
+ continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
+ : parent(boost::move(f)),
+ continuation(boost::move(c))
+ {
+ }
+
+ void init(boost::unique_lock<boost::mutex> &lock)
+ {
+ parent.future_->set_continuation_ptr(this->shared_from_this(), lock);
+ }
+
+ void call()
+ {
+ try {
+ this->continuation(boost::move(this->parent));
+ this->mark_finished_with_result();
+ } catch(...) {
+ this->mark_exceptional_finish();
+ }
+ // make sure parent is really cleared to prevent memory "leaks"
+ this->parent = F();
+ }
+
+ void call(boost::unique_lock<boost::mutex>& lck) {
+ try {
+ {
+ relocker relock(lck);
+ // neither continuation nor parent are protected by the lock - call() must only
+ // be called once, and no one else must modify it.
+ this->continuation(boost::move(this->parent));
+
+ // make sure parent is really cleared to prevent memory "leaks"
+ this->parent = F();
+ }
+ this->mark_finished_with_result_internal(lck);
+ } catch (...) {
+ this->mark_exceptional_finish_internal(current_exception(), lck);
+
+ // make sure parent is really cleared to prevent memory "leaks"
+ relocker relock(lck);
+ this->parent = F();
+ }
+ }
+
+ static void run(shared_ptr<boost::detail::shared_state_base> that_)
+ {
+ continuation_shared_state* that = static_cast<continuation_shared_state*>(that_.get());
+ that->call();
+ }
+
+ ~continuation_shared_state() {}
+ };
+ /////////////////////////
+ /// future_async_continuation_shared_state
+ /////////////////////////
+
+ template<typename F, typename Rp, typename Fp>
+ struct future_async_continuation_shared_state: continuation_shared_state<F,Rp,Fp,continuation_shared_state_base<Rp> >
+ {
+ typedef continuation_shared_state<F,Rp,Fp,continuation_shared_state_base<Rp> > base_type;
+ public:
+ future_async_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
+ : base_type(boost::move(f), boost::forward<Fp>(c))
+ { }
+
+ void launch_continuation() {
+#if defined BOOST_THREAD_CONTINUATION_SYNC
+ this->call();
+#elif defined BOOST_THREAD_FUTURE_BLOCKING
+ boost::lock_guard<boost::mutex> lk(this->mutex);
+ this->thr_ = thread(&future_async_continuation_shared_state::run, static_shared_from_this(this));
+#else
+ thread(&future_async_continuation_shared_state::run, static_shared_from_this(this)).detach();
+#endif
+ }
+ };
+
+ /////////////////////////
+ /// future_executor_continuation_shared_state
+ /////////////////////////
+#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
+
+ template <typename FutureExecutorContinuationSharedState>
+ struct run_it {
+ shared_ptr<FutureExecutorContinuationSharedState> that_;
+
+#if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ BOOST_THREAD_COPYABLE_AND_MOVABLE(run_it)
+ run_it(run_it const& x) //BOOST_NOEXCEPT
+ : that_(x.that_)
+ {}
+ run_it& operator=(BOOST_THREAD_COPY_ASSIGN_REF(run_it) x) //BOOST_NOEXCEPT
+ {
+ if (this != &x) {
+ that_=x.that_;
+ }
+ return *this;
+ }
+ // move
+ run_it(BOOST_THREAD_RV_REF(run_it) x) BOOST_NOEXCEPT
+ : that_(x.that_)
+ {
+ x.that_.reset();
+ }
+ run_it& operator=(BOOST_THREAD_RV_REF(run_it) x) BOOST_NOEXCEPT {
+ if (this != &x) {
+ that_=x.that;
+ x.that_.reset();
+ }
+ return *this;
+ }
+#endif
+ run_it(shared_ptr<FutureExecutorContinuationSharedState> that) : that_ (that) {}
+
+ void operator()()
+ {
+ that_->run(that_);
+ }
+ };
+
+}
+ BOOST_THREAD_DCL_MOVABLE_BEG(F) detail::run_it<F> BOOST_THREAD_DCL_MOVABLE_END
+
+namespace detail {
+
+ template<typename F, typename Rp, typename Fp>
+ struct future_executor_continuation_shared_state: continuation_shared_state<F,Rp,Fp>
+ {
+ typedef continuation_shared_state<F,Rp,Fp> base_type;
+
+ public:
+ future_executor_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
+ : base_type(boost::move(f), boost::forward<Fp>(c))
+ {
+ }
+
+ template <class Ex>
+ void init(boost::unique_lock<boost::mutex> &lk, Ex& ex)
+ {
+ this->set_executor_policy(executor_ptr_type(new executor_ref<Ex>(ex)), lk);
+ this->base_type::init(lk);
+ }
+
+ void launch_continuation() {
+ run_it<base_type> fct(static_shared_from_this(this));
+ this->get_executor()->submit(boost::move(fct));
+ }
+
+ ~future_executor_continuation_shared_state() {}
+ };
+#endif
+
+ /////////////////////////
+ /// shared_future_async_continuation_shared_state
+ /////////////////////////
+
+ template<typename F, typename Rp, typename Fp>
+ struct shared_future_async_continuation_shared_state: continuation_shared_state<F,Rp,Fp,continuation_shared_state_base<Rp> >
+ {
+ typedef continuation_shared_state<F,Rp,Fp,continuation_shared_state_base<Rp> > base_type;
+
+ public:
+ shared_future_async_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
+ : base_type(boost::move(f), boost::forward<Fp>(c))
+ {
+ }
+
+ void launch_continuation() {
+#if defined BOOST_THREAD_CONTINUATION_SYNC
+ this->call();
+#elif defined BOOST_THREAD_FUTURE_BLOCKING
+ boost::lock_guard<boost::mutex> lk(this->mutex);
+ this->thr_ = thread(&shared_future_async_continuation_shared_state::run, static_shared_from_this(this));
+#else
+ thread(&shared_future_async_continuation_shared_state::run, static_shared_from_this(this)).detach();
+#endif
+ }
+
+ ~shared_future_async_continuation_shared_state() {}
+ };
+
+ /////////////////////////
+ /// shared_future_executor_continuation_shared_state
+ /////////////////////////
+#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
+
+ template<typename F, typename Rp, typename Fp>
+ struct shared_future_executor_continuation_shared_state: continuation_shared_state<F,Rp,Fp>
+ {
+ typedef continuation_shared_state<F,Rp,Fp> base_type;
+
+ public:
+
+ shared_future_executor_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
+ : base_type(boost::move(f), boost::forward<Fp>(c))
+ {
+ }
+
+ template <class Ex>
+ void init(boost::unique_lock<boost::mutex> &lk, Ex& ex)
+ {
+ this->set_executor_policy(executor_ptr_type(new executor_ref<Ex>(ex)), lk);
+ this->base_type::init(lk);
+ }
+
+ void launch_continuation() {
+ run_it<base_type> fct(static_shared_from_this(this));
+ this->get_executor()->submit(boost::move(fct));
+ }
+
+ ~shared_future_executor_continuation_shared_state() {}
+ };
+
+#endif
+ //////////////////////////
+ /// future_deferred_continuation_shared_state
+ //////////////////////////
+ template<typename F, typename Rp, typename Fp>
+ struct future_deferred_continuation_shared_state: continuation_shared_state<F,Rp,Fp>
+ {
+ typedef continuation_shared_state<F,Rp,Fp> base_type;
+ public:
+ future_deferred_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
+ : base_type(boost::move(f), boost::forward<Fp>(c))
+ {
+ this->set_deferred();
+ }
+
+ virtual void execute(boost::unique_lock<boost::mutex>& lk) {
+ this->parent.wait();
+ this->call(lk);
+ }
+
+ virtual void launch_continuation() { }
+ };
+
+ //////////////////////////
+ /// shared_future_deferred_continuation_shared_state
+ //////////////////////////
+ template<typename F, typename Rp, typename Fp>
+ struct shared_future_deferred_continuation_shared_state: continuation_shared_state<F,Rp,Fp>
+ {
+ typedef continuation_shared_state<F,Rp,Fp> base_type;
+
+ public:
+ shared_future_deferred_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
+ : base_type(boost::move(f), boost::forward<Fp>(c))
+ {
+ this->set_deferred();
+ }
+
+ virtual void execute(boost::unique_lock<boost::mutex>& lk) {
+ this->parent.wait();
+ this->call(lk);
+ }
+
+ virtual void launch_continuation() { }
+ };
+
+ ////////////////////////////////
+ // make_future_deferred_continuation_shared_state
+ ////////////////////////////////
+ template<typename F, typename Rp, typename Fp>
+ BOOST_THREAD_FUTURE<Rp>
+ make_future_deferred_continuation_shared_state(
+ boost::unique_lock<boost::mutex> &lock,
+ BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c) {
+ typedef typename decay<Fp>::type Cont;
+ shared_ptr<future_deferred_continuation_shared_state<F, Rp, Cont> >
+ h(new future_deferred_continuation_shared_state<F, Rp, Cont>(boost::move(f), boost::forward<Fp>(c)));
+ h->init(lock);
+ return BOOST_THREAD_FUTURE<Rp>(h);
+ }
+
+ ////////////////////////////////
+ // make_future_async_continuation_shared_state
+ ////////////////////////////////
+ template<typename F, typename Rp, typename Fp>
+ BOOST_THREAD_FUTURE<Rp>
+ make_future_async_continuation_shared_state(
+ boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f,
+ BOOST_THREAD_FWD_REF(Fp) c) {
+ typedef typename decay<Fp>::type Cont;
+ shared_ptr<future_async_continuation_shared_state<F,Rp, Cont> >
+ h(new future_async_continuation_shared_state<F,Rp, Cont>(boost::move(f), boost::forward<Fp>(c)));
+ h->init(lock);
+
+ return BOOST_THREAD_FUTURE<Rp>(h);
+ }
+
+ ////////////////////////////////
+ // make_future_executor_continuation_shared_state
+ ////////////////////////////////
+#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
+
+ template<typename Ex, typename F, typename Rp, typename Fp>
+ BOOST_THREAD_FUTURE<Rp>
+ make_future_executor_continuation_shared_state(Ex& ex,
+ boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f,
+ BOOST_THREAD_FWD_REF(Fp) c) {
+ typedef typename decay<Fp>::type Cont;
+ shared_ptr<future_executor_continuation_shared_state<F,Rp, Cont> >
+ h(new future_executor_continuation_shared_state<F,Rp, Cont>(boost::move(f), boost::forward<Fp>(c)));
+ h->init(lock, ex);
+
+ return BOOST_THREAD_FUTURE<Rp>(h);
+ }
+#endif
+
+ ////////////////////////////////
+ // make_shared_future_deferred_continuation_shared_state
+ ////////////////////////////////
+ template<typename F, typename Rp, typename Fp>
+ BOOST_THREAD_FUTURE<Rp>
+ make_shared_future_deferred_continuation_shared_state(
+ boost::unique_lock<boost::mutex> &lock,
+ F f, BOOST_THREAD_FWD_REF(Fp) c) {
+ typedef typename decay<Fp>::type Cont;
+ shared_ptr<shared_future_deferred_continuation_shared_state<F, Rp, Cont> >
+ h(new shared_future_deferred_continuation_shared_state<F, Rp, Cont>(f, boost::forward<Fp>(c)));
+ h->init(lock);
+
+ return BOOST_THREAD_FUTURE<Rp>(h);
+ }
+ ////////////////////////////////
+ // make_shared_future_async_continuation_shared_state
+ ////////////////////////////////
+ template<typename F, typename Rp, typename Fp>
+ BOOST_THREAD_FUTURE<Rp>
+ make_shared_future_async_continuation_shared_state(
+ boost::unique_lock<boost::mutex> &lock, F f,
+ BOOST_THREAD_FWD_REF(Fp) c) {
+ typedef typename decay<Fp>::type Cont;
+ shared_ptr<shared_future_async_continuation_shared_state<F,Rp, Cont> >
+ h(new shared_future_async_continuation_shared_state<F,Rp, Cont>(f, boost::forward<Fp>(c)));
+ h->init(lock);
+
+ return BOOST_THREAD_FUTURE<Rp>(h);
+ }
+ ////////////////////////////////
+ // make_shared_future_executor_continuation_shared_state
+ ////////////////////////////////
+#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
+ template<typename Ex, typename F, typename Rp, typename Fp>
+ BOOST_THREAD_FUTURE<Rp>
+ make_shared_future_executor_continuation_shared_state(Ex& ex,
+ boost::unique_lock<boost::mutex> &lock, F f,
+ BOOST_THREAD_FWD_REF(Fp) c) {
+ typedef typename decay<Fp>::type Cont;
+ shared_ptr<shared_future_executor_continuation_shared_state<F, Rp, Cont> >
+ h(new shared_future_executor_continuation_shared_state<F, Rp, Cont>(f, boost::forward<Fp>(c)));
+ h->init(lock, ex);
+
+ return BOOST_THREAD_FUTURE<Rp>(h);
+ }
+#endif
+}
+
+ ////////////////////////////////
+ // template<typename F>
+ // auto future<R>::then(launch policy, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
+ ////////////////////////////////
+ template <typename R>
+ template <typename F>
+ inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type>
+ BOOST_THREAD_FUTURE<R>::then(launch policy, BOOST_THREAD_FWD_REF(F) func) {
+ typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
+ BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
+
+ // keep state alive as we move ourself but hold the lock
+ shared_ptr<detail::shared_state_base> sentinel(this->future_);
+ boost::unique_lock<boost::mutex> lock(sentinel->mutex);
+
+ if (underlying_cast<int>(policy) & int(launch::async)) {
+ return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
+ lock, boost::move(*this), boost::forward<F>(func)
+ )));
+ } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
+ return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
+ lock, boost::move(*this), boost::forward<F>(func)
+ )));
+#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
+ } else if (underlying_cast<int>(policy) & int(launch::executor)) {
+ assert(this->future_->get_executor());
+ typedef executor Ex;
+ Ex& ex = *(this->future_->get_executor());
+ return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type>(ex,
+ lock, boost::move(*this), boost::forward<F>(func)
+ )));
+#endif
+ } else if (underlying_cast<int>(policy) & int(launch::inherit)) {
+
+ launch policy = this->launch_policy(lock);
+ if (underlying_cast<int>(policy) & int(launch::async)) {
+ return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
+ lock, boost::move(*this), boost::forward<F>(func)
+ )));
+ } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
+ return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
+ lock, boost::move(*this), boost::forward<F>(func)
+ )));
+#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
+ } else if (underlying_cast<int>(policy) & int(launch::executor)) {
+ assert(this->future_->get_executor());
+ typedef executor Ex;
+ Ex& ex = *(this->future_->get_executor());
+ return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type>(ex,
+ lock, boost::move(*this), boost::forward<F>(func)
+ )));
+#endif
+ } else {
+ return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
+ lock, boost::move(*this), boost::forward<F>(func)
+ )));
+ }
+ } else {
+ return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
+ lock, boost::move(*this), boost::forward<F>(func)
+ )));
+ }
+ }
+#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
+ ////////////////////////////////
+ // template<typename Ex, typename F>
+ // auto future<future<R2> >::then(Ex&, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
+ ////////////////////////////////
+ template <typename R>
+ template <typename Ex, typename F>
+ inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type>
+ BOOST_THREAD_FUTURE<R>::then(Ex& ex, BOOST_THREAD_FWD_REF(F) func) {
+ typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
+ BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
+
+ // keep state alive as we move ourself but hold the lock
+ shared_ptr<detail::shared_state_base> sentinel(this->future_);
+ boost::unique_lock<boost::mutex> lock(sentinel->mutex);
+
+ return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type>(ex,
+ lock, boost::move(*this), boost::forward<F>(func)
+ )));
+ }
+#endif
+ ////////////////////////////////
+ // template<typename F>
+ // auto future<future<R2> >::then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
+ ////////////////////////////////
+ template <typename R>
+ template <typename F>
+ inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type>
+ BOOST_THREAD_FUTURE<R>::then(BOOST_THREAD_FWD_REF(F) func) {
+
+#ifndef BOOST_THREAD_CONTINUATION_SYNC
+ return this->then(this->launch_policy(), boost::forward<F>(func));
+#else
+ typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
+ BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
+
+ // keep state alive as we move ourself but hold the lock
+ shared_ptr<detail::shared_state_base> sentinel(this->future_);
+ boost::unique_lock<boost::mutex> lock(sentinel->mutex);
+
+ launch policy = this->launch_policy(lock);
+ if (underlying_cast<int>(policy) & int(launch::deferred)) {
+ return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
+ lock, boost::move(*this), boost::forward<F>(func)
+ )));
+ } else {
+ return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
+ lock, boost::move(*this), boost::forward<F>(func)
+ )));
+ }
+#endif
+
+ }
+
+ ////////////////////////////////
+ // template<typename F>
+ // auto future<future<R2> >::then(launch, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
+ ////////////////////////////////
+ template <typename R2>
+ template <typename F>
+ inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >)>::type>
+ BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >::then(launch policy, BOOST_THREAD_FWD_REF(F) func) {
+ typedef BOOST_THREAD_FUTURE<R2> R;
+ typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
+ BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
+
+ // keep state alive as we move ourself but hold the lock
+ shared_ptr<detail::shared_state_base> sentinel(this->future_);
+ boost::unique_lock<boost::mutex> lock(sentinel->mutex);
+
+ if (underlying_cast<int>(policy) & int(launch::async)) {
+ return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
+ lock, boost::move(*this), boost::forward<F>(func)
+ )));
+ } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
+ return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
+ lock, boost::move(*this), boost::forward<F>(func)
+ )));
+#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
+ } else if (underlying_cast<int>(policy) & int(launch::executor)) {
+ assert(this->future_->get_executor());
+ typedef executor Ex;
+ Ex& ex = *(this->future_->get_executor());
+ return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type>(ex,
+ lock, boost::move(*this), boost::forward<F>(func)
+ )));
+#endif
+ } else if (underlying_cast<int>(policy) & int(launch::inherit)) {
+ launch policy = this->launch_policy(lock);
+
+ if (underlying_cast<int>(policy) & int(launch::async)) {
+ return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
+ lock, boost::move(*this), boost::forward<F>(func)
+ )));
+ } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
+ return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
+ lock, boost::move(*this), boost::forward<F>(func)
+ )));
+#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
+ } else if (underlying_cast<int>(policy) & int(launch::executor)) {
+ assert(this->future_->get_executor());
+ typedef executor Ex;
+ Ex& ex = *(this->future_->get_executor());
+ return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type>(ex,
+ lock, boost::move(*this), boost::forward<F>(func)
+ )));
+#endif
+ } else {
+ return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
+ lock, boost::move(*this), boost::forward<F>(func)
+ )));
+ }
+ } else {
+ return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
+ lock, boost::move(*this), boost::forward<F>(func)
+ )));
+ }
+ }
+
+#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
+ ////////////////////////////////
+ // template<typename Ex, typename F>
+ // auto future<future<R2> >::then(Ex&, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
+ ////////////////////////////////
+ template <typename R2>
+ template <typename Ex, typename F>
+ inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >)>::type>
+ BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >::then(Ex& ex, BOOST_THREAD_FWD_REF(F) func) {
+ typedef BOOST_THREAD_FUTURE<R2> R;
+ typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
+ BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
+
+ // keep state alive as we move ourself but hold the lock
+ shared_ptr<detail::shared_state_base> sentinel(this->future_);
+ boost::unique_lock<boost::mutex> lock(sentinel->mutex);
+
+ return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type>(ex,
+ lock, boost::move(*this), boost::forward<F>(func)
+ )));
+ }
+#endif
+
+ ////////////////////////////////
+ // template<typename F>
+ // auto future<future<R2> >::then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
+ ////////////////////////////////
+ template <typename R2>
+ template <typename F>
+ inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >)>::type>
+ BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >::then(BOOST_THREAD_FWD_REF(F) func) {
+
+#ifndef BOOST_THREAD_CONTINUATION_SYNC
+ return this->then(this->launch_policy(), boost::forward<F>(func));
+#else
+ typedef BOOST_THREAD_FUTURE<R2> R;
+ typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
+ BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
+
+ // keep state alive as we move ourself but hold the lock
+ shared_ptr<detail::shared_state_base> sentinel(this->future_);
+ boost::unique_lock<boost::mutex> lock(sentinel->mutex);
+
+ launch policy = this->launch_policy(lock);
+
+ if (underlying_cast<int>(policy) & int(launch::deferred)) {
+ return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
+ lock, boost::move(*this), boost::forward<F>(func)
+ )));
+ } else {
+ return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
+ lock, boost::move(*this), boost::forward<F>(func)
+ )));
+ }
+#endif
+ }
+
+ ////////////////////////////////
+ // template<typename F>
+ // auto shared_future<R>::then(launch policy, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
+ ////////////////////////////////
+ template <typename R>
+ template <typename F>
+ inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future<R>)>::type>
+ shared_future<R>::then(launch policy, BOOST_THREAD_FWD_REF(F) func) const
+ {
+ typedef typename boost::result_of<F(shared_future<R>)>::type future_type;
+ BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
+
+ boost::unique_lock<boost::mutex> lock(this->future_->mutex);
+ if (underlying_cast<int>(policy) & int(launch::async)) {
+ return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type>(
+ lock, *this, boost::forward<F>(func)
+ )));
+ } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
+ return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_deferred_continuation_shared_state<shared_future<R>, future_type>(
+ lock, *this, boost::forward<F>(func)
+ )));
+#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
+ } else if (underlying_cast<int>(policy) & int(launch::executor)) {
+ typedef executor Ex;
+ Ex& ex = *(this->future_->get_executor());
+ return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_executor_continuation_shared_state<Ex, shared_future<R>, future_type>(ex,
+ lock, *this, boost::forward<F>(func)
+ )));
+#endif
+ } else if (underlying_cast<int>(policy) & int(launch::inherit)) {
+
+ launch policy = this->launch_policy(lock);
+ if (underlying_cast<int>(policy) & int(launch::async)) {
+ return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type>(
+ lock, *this, boost::forward<F>(func)
+ )));
+ } else if (underlying_cast<int>(policy) & int(launch::deferred)) {
+ return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_deferred_continuation_shared_state<shared_future<R>, future_type>(
+ lock, *this, boost::forward<F>(func)
+ )));
+#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
+ } else if (underlying_cast<int>(policy) & int(launch::executor)) {
+ typedef executor Ex;
+ Ex& ex = *(this->future_->get_executor());
+ return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_executor_continuation_shared_state<Ex, shared_future<R>, future_type>(ex,
+ lock, *this, boost::forward<F>(func)
+ )));
+#endif
+ } else {
+ return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type>(
+ lock, *this, boost::forward<F>(func)
+ )));
+ }
+
+ } else {
+ return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type>(
+ lock, *this, boost::forward<F>(func)
+ )));
+ }
+ }
+#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
+ ////////////////////////////////
+ // template<typename Ex, typename F>
+ // auto shared_future<R>::then(Ex&, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
+ ////////////////////////////////
+ template <typename R>
+ template <typename Ex, typename F>
+ inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future<R>)>::type>
+ shared_future<R>::then(Ex& ex, BOOST_THREAD_FWD_REF(F) func) const
+ {
+ typedef typename boost::result_of<F(shared_future<R>)>::type future_type;
+ BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
+
+ boost::unique_lock<boost::mutex> lock(this->future_->mutex);
+ return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_executor_continuation_shared_state<Ex, shared_future<R>, future_type>(ex,
+ lock, *this, boost::forward<F>(func)
+ )));
+ }
+#endif
+
+ ////////////////////////////////
+ // template<typename F>
+ // auto shared_future<R>::then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
+ ////////////////////////////////
+ template <typename R>
+ template <typename F>
+ inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future<R>)>::type>
+ shared_future<R>::then(BOOST_THREAD_FWD_REF(F) func) const {
+#ifndef BOOST_THREAD_CONTINUATION_SYNC
+ return this->then(this->launch_policy(), boost::forward<F>(func));
+#else
+ typedef typename boost::result_of<F(shared_future<R>)>::type future_type;
+ BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
+
+ boost::unique_lock<boost::mutex> lock(this->future_->mutex);
+ launch policy = this->launch_policy(lock);
+ if (underlying_cast<int>(policy) & int(launch::deferred)) {
+ return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_deferred_continuation_shared_state<shared_future<R>, future_type>(
+ lock, *this, boost::forward<F>(func)
+ )));
+ } else {
+ return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type>(
+ lock, *this, boost::forward<F>(func)
+ )));
+ }
+#endif
+ }
+
+namespace detail
+{
+ template <typename T>
+ struct mfallbacker_to
+ {
+ T value_;
+ typedef T result_type;
+ mfallbacker_to(BOOST_THREAD_RV_REF(T) v)
+ : value_(boost::move(v))
+ {}
+
+ T operator()(BOOST_THREAD_FUTURE<T> fut) {
+ return fut.get_or(boost::move(value_));
+ }
+ };
+ template <typename T>
+ struct cfallbacker_to
+ {
+ T value_;
+ typedef T result_type;
+ cfallbacker_to(T const& v)
+ : value_(v)
+ {}
+
+ T operator()(BOOST_THREAD_FUTURE<T> fut) const {
+ return fut.get_or(value_);
+
+ }
+ };
+}
+ ////////////////////////////////
+ // future<R> future<R>::fallback_to(R&& v);
+ ////////////////////////////////
+
+ template <typename R>
+ template <typename R2>
+ inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type
+ BOOST_THREAD_FUTURE<R>::fallback_to(BOOST_THREAD_RV_REF(R2) v) {
+ return then(detail::mfallbacker_to<R>(boost::move(v)));
+ }
+
+ template <typename R>
+ template <typename R2>
+ inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type
+ BOOST_THREAD_FUTURE<R>::fallback_to(R2 const& v) {
+ return then(detail::cfallbacker_to<R>(v));
+ }
+
+#endif
+
+#if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
+namespace detail
+{
+ /////////////////////////
+ /// future_unwrap_shared_state
+ /////////////////////////
+
+ template<typename F, typename Rp>
+ struct future_unwrap_shared_state: shared_state<Rp>
+ {
+ F wrapped;
+ typename F::value_type unwrapped;
+ public:
+ explicit future_unwrap_shared_state(BOOST_THREAD_RV_REF(F) f)
+ : wrapped(boost::move(f)) {
+ }
+
+ void launch_continuation()
+ {
+ boost::unique_lock<boost::mutex> lk(this->mutex);
+ // assert(wrapped.is_ready());
+ if (! unwrapped.valid() )
+ {
+ if (wrapped.has_exception()) {
+ this->mark_exceptional_finish_internal(wrapped.get_exception_ptr(), lk);
+ } else {
+ unwrapped = wrapped.get();
+ if (unwrapped.valid())
+ {
+ lk.unlock();
+ boost::unique_lock<boost::mutex> lk2(unwrapped.future_->mutex);
+ unwrapped.future_->set_continuation_ptr(this->shared_from_this(), lk2);
+ } else {
+ this->mark_exceptional_finish_internal(boost::copy_exception(future_uninitialized()), lk);
+ }
+ }
+ } else {
+ // assert(unwrapped.is_ready());
+ if (unwrapped.has_exception()) {
+ this->mark_exceptional_finish_internal(unwrapped.get_exception_ptr(), lk);
+ } else {
+ this->mark_finished_with_result_internal(unwrapped.get(), lk);
+ }
+ }
+ }
+ };
+
+ template<typename F>
+ struct future_unwrap_shared_state<F,void>: shared_state<void>
+ {
+ F wrapped;
+ typename F::value_type unwrapped;
+ public:
+ explicit future_unwrap_shared_state(BOOST_THREAD_RV_REF(F) f)
+ : wrapped(boost::move(f)) {
+ }
+
+ void launch_continuation()
+ {
+ boost::unique_lock<boost::mutex> lk(this->mutex);
+ // assert(wrapped.is_ready());
+ if (! unwrapped.valid() )
+ {
+ if (wrapped.has_exception()) {
+ this->mark_exceptional_finish_internal(wrapped.get_exception_ptr(), lk);
+ } else {
+ unwrapped = wrapped.get();
+ if (unwrapped.valid())
+ {
+ lk.unlock();
+ boost::unique_lock<boost::mutex> lk2(unwrapped.future_->mutex);
+ unwrapped.future_->set_continuation_ptr(this->shared_from_this(), lk2);
+ } else {
+ this->mark_exceptional_finish_internal(boost::copy_exception(future_uninitialized()), lk);
+ }
+ }
+ } else {
+ // assert(unwrapped.is_ready());
+ if (unwrapped.has_exception()) {
+ this->mark_exceptional_finish_internal(unwrapped.get_exception_ptr(), lk);
+ } else {
+ this->mark_finished_with_result_internal(lk);
+ }
+ }
+ }
+ };
+
+ template <class F, class Rp>
+ BOOST_THREAD_FUTURE<Rp>
+ make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f) {
+ shared_ptr<future_unwrap_shared_state<F, Rp> >
+ h(new future_unwrap_shared_state<F, Rp>(boost::move(f)));
+ h->wrapped.future_->set_continuation_ptr(h, lock);
+
+ return BOOST_THREAD_FUTURE<Rp>(h);
+ }
+}
+
+ template <typename R>
+ inline BOOST_THREAD_FUTURE<R>::BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R> >) other)
+ : base_type(other.unwrap()) {}
+
+ template <typename R2>
+ BOOST_THREAD_FUTURE<R2>
+ BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >::unwrap()
+ {
+ BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
+
+ // keep state alive as we move ourself but hold the lock
+ shared_ptr<detail::shared_state_base> sentinel(this->future_);
+ boost::unique_lock<boost::mutex> lock(sentinel->mutex);
+
+ return boost::detail::make_future_unwrap_shared_state<BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >, R2>(lock, boost::move(*this));
+ }
+#endif
+
+#if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
+namespace detail
+{
+ struct input_iterator_tag {};
+ struct vector_tag {};
+ struct values_tag {};
+ template <typename T>
+ struct alias_t { typedef T type; };
+
+ BOOST_CONSTEXPR_OR_CONST input_iterator_tag input_iterator_tag_value = {};
+ BOOST_CONSTEXPR_OR_CONST vector_tag vector_tag_value = {};
+ BOOST_CONSTEXPR_OR_CONST values_tag values_tag_value = {};
+ ////////////////////////////////
+ // detail::future_async_when_all_shared_state
+ ////////////////////////////////
+ template<typename F>
+ struct future_when_all_vector_shared_state: future_async_shared_state_base<csbl::vector<F> >
+ {
+ typedef csbl::vector<F> vector_type;
+ typedef typename F::value_type value_type;
+ vector_type vec_;
+
+ static void run(shared_ptr<boost::detail::shared_state_base> that_) {
+ future_when_all_vector_shared_state* that = static_cast<future_when_all_vector_shared_state*>(that_.get());
+ try {
+ boost::wait_for_all(that->vec_.begin(), that->vec_.end());
+ that->mark_finished_with_result(boost::move(that->vec_));
+ } catch(...) {
+ that->mark_exceptional_finish();
+ }
+ }
+ bool run_deferred() {
+
+ bool res = false;
+ for (typename csbl::vector<F>::iterator it = vec_.begin(); it != vec_.end(); ++it) {
+ if (! it->run_if_is_deferred())
+ {
+ res = true;
+ }
+ }
+ return res;
+ }
+ void init() {
+ if (! run_deferred())
+ {
+ future_when_all_vector_shared_state::run(this->shared_from_this());
+ return;
+ }
+#ifdef BOOST_THREAD_FUTURE_BLOCKING
+ this->thr_ = thread(&future_when_all_vector_shared_state::run, this->shared_from_this());
+#else
+ thread(&future_when_all_vector_shared_state::run, this->shared_from_this()).detach();
+#endif
+ }
+
+ public:
+ template< typename InputIterator>
+ future_when_all_vector_shared_state(input_iterator_tag, InputIterator first, InputIterator last)
+ : vec_(std::make_move_iterator(first), std::make_move_iterator(last))
+ {
+ }
+
+ future_when_all_vector_shared_state(vector_tag, BOOST_THREAD_RV_REF(csbl::vector<F>) v)
+ : vec_(boost::move(v))
+ {
+ }
+
+#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template< typename T0, typename ...T>
+ future_when_all_vector_shared_state(values_tag, BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures) {
+ vec_.push_back(boost::forward<T0>(f));
+ typename alias_t<char[]>::type{
+ ( //first part of magic unpacker
+ vec_.push_back(boost::forward<T>(futures)),'0'
+ )..., '0'
+ }; //second part of magic unpacker
+ }
+#endif
+
+ ~future_when_all_vector_shared_state() {}
+ };
+
+ ////////////////////////////////
+ // detail::future_async_when_any_shared_state
+ ////////////////////////////////
+ template<typename F>
+ struct future_when_any_vector_shared_state: future_async_shared_state_base<csbl::vector<F> >
+ {
+ typedef csbl::vector<F> vector_type;
+ typedef typename F::value_type value_type;
+ vector_type vec_;
+
+ static void run(shared_ptr<boost::detail::shared_state_base> that_)
+ {
+ future_when_any_vector_shared_state* that = static_cast<future_when_any_vector_shared_state*>(that_.get());
+ try {
+ boost::wait_for_any(that->vec_.begin(), that->vec_.end());
+ that->mark_finished_with_result(boost::move(that->vec_));
+ } catch(...) {
+ that->mark_exceptional_finish();
+ }
+ }
+ bool run_deferred() {
+
+ for (typename csbl::vector<F>::iterator it = vec_.begin(); it != vec_.end(); ++it) {
+ if (it->run_if_is_deferred_or_ready())
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ void init() {
+ if (run_deferred())
+ {
+ future_when_any_vector_shared_state::run(this->shared_from_this());
+ return;
+ }
+
+#ifdef BOOST_THREAD_FUTURE_BLOCKING
+ this->thr_ = thread(&future_when_any_vector_shared_state::run, this->shared_from_this());
+#else
+ thread(&future_when_any_vector_shared_state::run, this->shared_from_this()).detach();
+#endif
+ }
+
+ public:
+ template< typename InputIterator>
+ future_when_any_vector_shared_state(input_iterator_tag, InputIterator first, InputIterator last)
+ : vec_(std::make_move_iterator(first), std::make_move_iterator(last))
+ {
+ }
+
+ future_when_any_vector_shared_state(vector_tag, BOOST_THREAD_RV_REF(csbl::vector<F>) v)
+ : vec_(boost::move(v))
+ {
+ }
+
+#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template< typename T0, typename ...T>
+ future_when_any_vector_shared_state(values_tag,
+ BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures
+ ) {
+ vec_.push_back(boost::forward<T0>(f));
+ typename alias_t<char[]>::type{
+ ( //first part of magic unpacker
+ vec_.push_back(boost::forward<T>(futures))
+ ,'0'
+ )...,
+ '0'
+ }; //second part of magic unpacker
+ }
+#endif
+
+ ~future_when_any_vector_shared_state() {}
+ };
+
+#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ struct wait_for_all_fctr {
+ template <class ...T>
+ void operator()(T&&... v) {
+ boost::wait_for_all(boost::forward<T>(v)...);
+ }
+ };
+
+ struct wait_for_any_fctr {
+ template <class ...T>
+ void operator()(T&&... v) {
+ boost::wait_for_any(boost::forward<T>(v)...);
+ }
+ };
+
+
+ template <class Tuple, std::size_t i=csbl::tuple_size<Tuple>::value>
+ struct accumulate_run_if_is_deferred {
+ bool operator ()(Tuple& t)
+ {
+ return (! csbl::get<i-1>(t).run_if_is_deferred()) || accumulate_run_if_is_deferred<Tuple,i-1>()(t);
+ }
+ };
+ template <class Tuple>
+ struct accumulate_run_if_is_deferred<Tuple, 0> {
+ bool operator ()(Tuple& )
+ {
+ return false;
+ }
+ };
+
+
+ template< typename Tuple, typename T0, typename ...T>
+ struct future_when_all_tuple_shared_state: future_async_shared_state_base<Tuple>
+ {
+ Tuple tup_;
+ typedef typename make_tuple_indices<1+sizeof...(T)>::type Index;
+
+ static void run(shared_ptr<boost::detail::shared_state_base> that_) {
+ future_when_all_tuple_shared_state* that = static_cast<future_when_all_tuple_shared_state*>(that_.get());
+ try {
+ // TODO make use of apply(that->tup_, boost::detail::wait_for_all_fctor());
+ that->wait_for_all(Index());
+
+ that->mark_finished_with_result(boost::move(that->tup_));
+ } catch(...) {
+ that->mark_exceptional_finish();
+ }
+ }
+
+ template <size_t ...Indices>
+ void wait_for_all(tuple_indices<Indices...>) {
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ return invoke<void>(wait_for_all_fctr(), csbl::get<Indices>(tup_)...);
+#else
+ return wait_for_all_fctr()(csbl::get<Indices>(tup_)...);
+#endif
+ }
+
+ bool run_deferred() {
+
+ return accumulate_run_if_is_deferred<Tuple>()(tup_);
+ }
+ void init() {
+ if (! run_deferred())
+ {
+ future_when_all_tuple_shared_state::run(this->shared_from_this());
+ return;
+ }
+#ifdef BOOST_THREAD_FUTURE_BLOCKING
+ this->thr_ = thread(&future_when_all_tuple_shared_state::run, this->shared_from_this());
+#else
+ thread(&future_when_all_tuple_shared_state::run, this->shared_from_this()).detach();
+#endif
+
+ }
+ public:
+ template< typename F, typename ...Fs>
+ future_when_all_tuple_shared_state(values_tag, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(Fs) ... futures) :
+ tup_(boost::csbl::make_tuple(boost::forward<F>(f), boost::forward<Fs>(futures)...))
+ {
+ }
+
+ ~future_when_all_tuple_shared_state() {}
+
+ };
+
+
+ template <class Tuple, std::size_t i=csbl::tuple_size<Tuple>::value>
+ struct apply_any_run_if_is_deferred_or_ready {
+ bool operator ()(Tuple& t)
+ {
+ if (csbl::get<i-1>(t).run_if_is_deferred_or_ready()) return true;
+ return apply_any_run_if_is_deferred_or_ready<Tuple,i-1>()(t);
+ }
+ };
+ template <class Tuple>
+ struct apply_any_run_if_is_deferred_or_ready<Tuple, 0> {
+ bool operator ()(Tuple& )
+ {
+ return false;
+ }
+ };
+
+ template< typename Tuple, typename T0, typename ...T >
+ struct future_when_any_tuple_shared_state: future_async_shared_state_base<Tuple>
+ {
+ Tuple tup_;
+ typedef typename make_tuple_indices<1+sizeof...(T)>::type Index;
+
+ static void run(shared_ptr<boost::detail::shared_state_base> that_)
+ {
+ future_when_any_tuple_shared_state* that = static_cast<future_when_any_tuple_shared_state*>(that_.get());
+ try {
+ // TODO make use of apply(that->tup_, wait_for_any_fctr);
+ that->wait_for_any(Index());
+
+ that->mark_finished_with_result(boost::move(that->tup_));
+ } catch(...) {
+ that->mark_exceptional_finish();
+ }
+ }
+ template <size_t ...Indices>
+ void wait_for_any(tuple_indices<Indices...>) {
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ return invoke<void>(wait_for_any_fctr(), csbl::get<Indices>(tup_)...);
+#else
+ return wait_for_any_fctr()(csbl::get<Indices>(tup_)...);
+#endif
+ }
+ bool run_deferred() {
+ return apply_any_run_if_is_deferred_or_ready<Tuple>()(tup_);
+ }
+ void init() {
+ if (run_deferred())
+ {
+ future_when_any_tuple_shared_state::run(this->shared_from_this());
+ return;
+ }
+
+#ifdef BOOST_THREAD_FUTURE_BLOCKING
+ this->thr_ = thread(&future_when_any_tuple_shared_state::run, this->shared_from_this());
+#else
+ thread(&future_when_any_tuple_shared_state::run, this->shared_from_this()).detach();
+#endif
+ }
+
+ public:
+ template< typename F, typename ...Fs>
+ future_when_any_tuple_shared_state(values_tag,
+ BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(Fs) ... futures
+ ) :
+ tup_(boost::csbl::make_tuple(boost::forward<F>(f), boost::forward<Fs>(futures)...))
+ {
+ }
+
+ ~future_when_any_tuple_shared_state() {}
+ };
+#endif
+
+}
+
+ template< typename InputIterator>
+ typename boost::disable_if<is_future_type<InputIterator>,
+ BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type> >
+ >::type
+ when_all(InputIterator first, InputIterator last) {
+ typedef typename InputIterator::value_type value_type;
+ typedef csbl::vector<value_type> container_type;
+ typedef detail::future_when_all_vector_shared_state<value_type> factory_type;
+
+ if (first==last) return make_ready_future(container_type());
+ shared_ptr<factory_type >
+ h(new factory_type(detail::input_iterator_tag_value, first,last));
+ h->init();
+ return BOOST_THREAD_FUTURE<container_type>(h);
+ }
+
+ inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_all() {
+ return make_ready_future(csbl::tuple<>());
+ }
+
+#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template< typename T0, typename ...T>
+ BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
+ when_all(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures) {
+ typedef csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> container_type;
+ typedef detail::future_when_all_tuple_shared_state<container_type, typename decay<T0>::type, typename decay<T>::type...> factory_type;
+
+ shared_ptr<factory_type>
+ h(new factory_type(detail::values_tag_value, boost::forward<T0>(f), boost::forward<T>(futures)...));
+ h->init();
+ return BOOST_THREAD_FUTURE<container_type>(h);
+ }
+#endif
+
+ template< typename InputIterator>
+ typename boost::disable_if<is_future_type<InputIterator>,
+ BOOST_THREAD_FUTURE<csbl::vector<typename InputIterator::value_type> >
+ >::type
+ when_any(InputIterator first, InputIterator last) {
+ typedef typename InputIterator::value_type value_type;
+ typedef csbl::vector<value_type> container_type;
+ typedef detail::future_when_any_vector_shared_state<value_type> factory_type;
+
+ if (first==last) return make_ready_future(container_type());
+ shared_ptr<factory_type >
+ h(new factory_type(detail::input_iterator_tag_value, first,last));
+ h->init();
+ return BOOST_THREAD_FUTURE<container_type>(h);
+ }
+
+ inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_any() {
+ return make_ready_future(csbl::tuple<>());
+ }
+
+#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template< typename T0, typename ...T>
+ BOOST_THREAD_FUTURE<csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> >
+ when_any(BOOST_THREAD_FWD_REF(T0) f, BOOST_THREAD_FWD_REF(T) ... futures) {
+ typedef csbl::tuple<typename decay<T0>::type, typename decay<T>::type...> container_type;
+ typedef detail::future_when_any_tuple_shared_state<container_type, typename decay<T0>::type, typename decay<T>::type...> factory_type;
+
+ shared_ptr<factory_type>
+ h(new factory_type(detail::values_tag_value, boost::forward<T0>(f), boost::forward<T>(futures)...));
+ h->init();
+ return BOOST_THREAD_FUTURE<container_type>(h);
+ }
+#endif
+#endif // BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
+}
+
+#endif // BOOST_NO_EXCEPTION
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/futures/future_error.hpp b/src/third_party/boost-1.60.0/boost/thread/futures/future_error.hpp
new file mode 100644
index 00000000000..6212deece36
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/futures/future_error.hpp
@@ -0,0 +1,98 @@
+// (C) Copyright 2008-10 Anthony Williams
+// (C) Copyright 2011-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)
+
+#ifndef BOOST_THREAD_FUTURES_FUTURE_ERROR_HPP
+#define BOOST_THREAD_FUTURES_FUTURE_ERROR_HPP
+
+#include <boost/thread/detail/config.hpp>
+
+#include <boost/thread/futures/future_error_code.hpp>
+#include <boost/system/error_code.hpp>
+
+#include <stdexcept>
+
+namespace boost
+{
+ class BOOST_SYMBOL_VISIBLE future_error
+ : public std::logic_error
+ {
+ system::error_code ec_;
+ public:
+ future_error(system::error_code ec)
+ : logic_error(ec.message()),
+ ec_(ec)
+ {
+ }
+
+ const system::error_code& code() const BOOST_NOEXCEPT
+ {
+ return ec_;
+ }
+ };
+
+ class BOOST_SYMBOL_VISIBLE future_uninitialized:
+ public future_error
+ {
+ public:
+ future_uninitialized() :
+ future_error(system::make_error_code(future_errc::no_state))
+ {}
+ };
+ class BOOST_SYMBOL_VISIBLE broken_promise:
+ public future_error
+ {
+ public:
+ broken_promise():
+ future_error(system::make_error_code(future_errc::broken_promise))
+ {}
+ };
+ class BOOST_SYMBOL_VISIBLE future_already_retrieved:
+ public future_error
+ {
+ public:
+ future_already_retrieved():
+ future_error(system::make_error_code(future_errc::future_already_retrieved))
+ {}
+ };
+ class BOOST_SYMBOL_VISIBLE promise_already_satisfied:
+ public future_error
+ {
+ public:
+ promise_already_satisfied():
+ future_error(system::make_error_code(future_errc::promise_already_satisfied))
+ {}
+ };
+
+ class BOOST_SYMBOL_VISIBLE task_already_started:
+ public future_error
+ {
+ public:
+ task_already_started():
+ future_error(system::make_error_code(future_errc::promise_already_satisfied))
+ {}
+ };
+
+ class BOOST_SYMBOL_VISIBLE task_moved:
+ public future_error
+ {
+ public:
+ task_moved():
+ future_error(system::make_error_code(future_errc::no_state))
+ {}
+ };
+
+ class promise_moved:
+ public future_error
+ {
+ public:
+ promise_moved():
+ future_error(system::make_error_code(future_errc::no_state))
+ {}
+ };
+}
+
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/futures/future_error_code.hpp b/src/third_party/boost-1.60.0/boost/thread/futures/future_error_code.hpp
new file mode 100644
index 00000000000..7c8b6f2696a
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/futures/future_error_code.hpp
@@ -0,0 +1,61 @@
+// (C) Copyright 2008-10 Anthony Williams
+// (C) Copyright 2011-2012,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)
+
+#ifndef BOOST_THREAD_FUTURES_FUTURE_ERROR_CODE_HPP
+#define BOOST_THREAD_FUTURES_FUTURE_ERROR_CODE_HPP
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/core/scoped_enum.hpp>
+#include <boost/system/error_code.hpp>
+#include <boost/type_traits/integral_constant.hpp>
+
+namespace boost
+{
+
+ //enum class future_errc
+ BOOST_SCOPED_ENUM_DECLARE_BEGIN(future_errc)
+ {
+ broken_promise = 1,
+ future_already_retrieved,
+ promise_already_satisfied,
+ no_state
+ }
+ BOOST_SCOPED_ENUM_DECLARE_END(future_errc)
+
+ namespace system
+ {
+ template <>
+ struct BOOST_SYMBOL_VISIBLE is_error_code_enum< ::boost::future_errc> : public true_type {};
+
+ #ifdef BOOST_NO_CXX11_SCOPED_ENUMS
+ template <>
+ struct BOOST_SYMBOL_VISIBLE is_error_code_enum< ::boost::future_errc::enum_type> : public true_type { };
+ #endif
+ } // system
+
+ BOOST_THREAD_DECL
+ const system::error_category& future_category() BOOST_NOEXCEPT;
+
+ namespace system
+ {
+ inline
+ error_code
+ make_error_code(future_errc e) BOOST_NOEXCEPT
+ {
+ return error_code(underlying_cast<int>(e), boost::future_category());
+ }
+
+ inline
+ error_condition
+ make_error_condition(future_errc e) BOOST_NOEXCEPT
+ {
+ return error_condition(underlying_cast<int>(e), boost::future_category());
+ }
+ } // system
+} // boost
+
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/futures/future_status.hpp b/src/third_party/boost-1.60.0/boost/thread/futures/future_status.hpp
new file mode 100644
index 00000000000..383ac4673cf
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/futures/future_status.hpp
@@ -0,0 +1,30 @@
+// (C) Copyright 2008-10 Anthony Williams
+// (C) Copyright 2011-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)
+
+#ifndef BOOST_THREAD_FUTURES_FUTURE_STATUS_HPP
+#define BOOST_THREAD_FUTURES_FUTURE_STATUS_HPP
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/core/scoped_enum.hpp>
+
+namespace boost
+{
+ //enum class future_status
+ BOOST_SCOPED_ENUM_DECLARE_BEGIN(future_status)
+ {
+ ready,
+ timeout,
+ deferred
+ }
+ BOOST_SCOPED_ENUM_DECLARE_END(future_status)
+ namespace future_state
+ {
+ enum state { uninitialized, waiting, ready, moved, deferred };
+ }
+}
+
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/futures/is_future_type.hpp b/src/third_party/boost-1.60.0/boost/thread/futures/is_future_type.hpp
new file mode 100644
index 00000000000..df7a680faae
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/futures/is_future_type.hpp
@@ -0,0 +1,21 @@
+// (C) Copyright 2008-10 Anthony Williams
+// (C) Copyright 2011-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)
+
+#ifndef BOOST_THREAD_FUTURES_IS_FUTURE_TYPE_HPP
+#define BOOST_THREAD_FUTURES_IS_FUTURE_TYPE_HPP
+
+#include <boost/type_traits/integral_constant.hpp>
+
+namespace boost
+{
+ template<typename T>
+ struct is_future_type : false_type
+ {
+ };
+}
+
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/futures/launch.hpp b/src/third_party/boost-1.60.0/boost/thread/futures/launch.hpp
new file mode 100644
index 00000000000..8eed42cf4d0
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/futures/launch.hpp
@@ -0,0 +1,31 @@
+// (C) Copyright 2008-10 Anthony Williams
+// (C) Copyright 2011-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)
+
+#ifndef BOOST_THREAD_FUTURES_LAUNCH_HPP
+#define BOOST_THREAD_FUTURES_LAUNCH_HPP
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/core/scoped_enum.hpp>
+
+namespace boost
+{
+ //enum class launch
+ BOOST_SCOPED_ENUM_DECLARE_BEGIN(launch)
+ {
+ none = 0,
+ async = 1,
+ deferred = 2,
+#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
+ executor = 4,
+#endif
+ inherit = 8,
+ any = async | deferred
+ }
+ BOOST_SCOPED_ENUM_DECLARE_END(launch)
+}
+
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/futures/wait_for_all.hpp b/src/third_party/boost-1.60.0/boost/thread/futures/wait_for_all.hpp
new file mode 100644
index 00000000000..90cc2b77cb3
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/futures/wait_for_all.hpp
@@ -0,0 +1,74 @@
+// (C) Copyright 2008-10 Anthony Williams
+// (C) Copyright 2011-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)
+
+#ifndef BOOST_THREAD_FUTURES_WAIT_FOR_ALL_HPP
+#define BOOST_THREAD_FUTURES_WAIT_FOR_ALL_HPP
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/futures/is_future_type.hpp>
+
+#include <boost/core/enable_if.hpp>
+
+namespace boost
+{
+ template<typename Iterator>
+ typename boost::disable_if<is_future_type<Iterator>,void>::type wait_for_all(Iterator begin,Iterator end)
+ {
+ for(Iterator current=begin;current!=end;++current)
+ {
+ current->wait();
+ }
+ }
+
+#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+ template<typename F1,typename F2>
+ typename boost::enable_if<is_future_type<F1>,void>::type wait_for_all(F1& f1,F2& f2)
+ {
+ f1.wait();
+ f2.wait();
+ }
+
+ template<typename F1,typename F2,typename F3>
+ void wait_for_all(F1& f1,F2& f2,F3& f3)
+ {
+ f1.wait();
+ f2.wait();
+ f3.wait();
+ }
+
+ template<typename F1,typename F2,typename F3,typename F4>
+ void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4)
+ {
+ f1.wait();
+ f2.wait();
+ f3.wait();
+ f4.wait();
+ }
+
+ template<typename F1,typename F2,typename F3,typename F4,typename F5>
+ void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5)
+ {
+ f1.wait();
+ f2.wait();
+ f3.wait();
+ f4.wait();
+ f5.wait();
+ }
+#else
+ template<typename F1, typename... Fs>
+ void wait_for_all(F1& f1, Fs&... fs)
+ {
+ bool dummy[] = { (f1.wait(), true), (fs.wait(), true)... };
+
+ // prevent unused parameter warning
+ (void) dummy;
+ }
+#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)}
+
+}
+
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/futures/wait_for_any.hpp b/src/third_party/boost-1.60.0/boost/thread/futures/wait_for_any.hpp
new file mode 100644
index 00000000000..b869a4318a8
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/futures/wait_for_any.hpp
@@ -0,0 +1,161 @@
+// (C) Copyright 2008-10 Anthony Williams
+// (C) Copyright 2011-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)
+
+#ifndef BOOST_THREAD_FUTURES_WAIT_FOR_ANY_HPP
+#define BOOST_THREAD_FUTURES_WAIT_FOR_ANY_HPP
+
+#include <boost/thread/detail/config.hpp>
+
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/futures/is_future_type.hpp>
+#include <boost/thread/lock_algorithms.hpp>
+#include <boost/thread/mutex.hpp>
+
+#include <boost/core/enable_if.hpp>
+#include <boost/next_prior.hpp>
+#include <boost/scoped_array.hpp>
+
+#include <iterator>
+#include <vector>
+
+namespace boost
+{
+ namespace detail
+ {
+ template <class Future>
+ class waiter_for_any_in_seq
+ {
+ struct registered_waiter;
+ typedef std::vector<int>::size_type count_type;
+
+ struct registered_waiter
+ {
+ typedef Future future_type;
+ future_type* future_;
+ typedef typename Future::notify_when_ready_handle notify_when_ready_handle;
+ notify_when_ready_handle handle;
+ count_type index;
+
+ registered_waiter(future_type & a_future,
+ notify_when_ready_handle handle_, count_type index_) :
+ future_(&a_future), handle(handle_), index(index_)
+ {
+ }
+ };
+
+ struct all_futures_lock
+ {
+#ifdef _MANAGED
+ typedef std::ptrdiff_t count_type_portable;
+#else
+ typedef count_type count_type_portable;
+#endif
+ count_type_portable count;
+ boost::scoped_array<boost::unique_lock<boost::mutex> > locks;
+
+ all_futures_lock(std::vector<registered_waiter>& waiters) :
+ count(waiters.size()), locks(new boost::unique_lock<boost::mutex>[count])
+ {
+ for (count_type_portable i = 0; i < count; ++i)
+ {
+ locks[i] = BOOST_THREAD_MAKE_RV_REF(boost::unique_lock<boost::mutex>(waiters[i].future_->mutex()));
+ }
+ }
+
+ void lock()
+ {
+ boost::lock(locks.get(), locks.get() + count);
+ }
+
+ void unlock()
+ {
+ for (count_type_portable i = 0; i < count; ++i)
+ {
+ locks[i].unlock();
+ }
+ }
+ };
+
+ boost::condition_variable_any cv;
+ std::vector<registered_waiter> waiters_;
+ count_type future_count;
+
+ public:
+ waiter_for_any_in_seq() :
+ future_count(0)
+ {
+ }
+
+ template <typename F>
+ void add(F& f)
+ {
+ if (f.valid())
+ {
+ registered_waiter waiter(f, f.notify_when_ready(cv), future_count);
+ try
+ {
+ waiters_.push_back(waiter);
+ }
+ catch (...)
+ {
+ f.future_->unnotify_when_ready(waiter.handle);
+ throw;
+ }
+ ++future_count;
+ }
+ }
+
+#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+ template <typename F1, typename ... Fs>
+ void add(F1& f1, Fs&... fs)
+ {
+ add(f1);
+ add(fs...);
+ }
+#endif
+
+ count_type wait()
+ {
+ all_futures_lock lk(waiters_);
+ for (;;)
+ {
+ for (count_type i = 0; i < waiters_.size(); ++i)
+ {
+ if (waiters_[i].future_->is_ready(lk.locks[i]))
+ {
+ return waiters_[i].index;
+ }
+ }
+ cv.wait(lk);
+ }
+ }
+
+ ~waiter_for_any_in_seq()
+ {
+ for (count_type i = 0; i < waiters_.size(); ++i)
+ {
+ waiters_[i].future_->unnotify_when_ready(waiters_[i].handle);
+ }
+ }
+ };
+ }
+
+ template <typename Iterator>
+ typename boost::disable_if<is_future_type<Iterator> , Iterator>::type wait_for_any(Iterator begin, Iterator end)
+ {
+ if (begin == end) return end;
+
+ detail::waiter_for_any_in_seq<typename std::iterator_traits<Iterator>::value_type> waiter;
+ for (Iterator current = begin; current != end; ++current)
+ {
+ waiter.add(*current);
+ }
+ return boost::next(begin, waiter.wait());
+ }
+}
+
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/is_locked_by_this_thread.hpp b/src/third_party/boost-1.60.0/boost/thread/is_locked_by_this_thread.hpp
new file mode 100644
index 00000000000..6344c0ff6dd
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/is_locked_by_this_thread.hpp
@@ -0,0 +1,39 @@
+// (C) Copyright 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)
+
+
+#ifndef BOOST_THREAD_IS_LOCKED_BY_THIS_THREAD_HPP
+#define BOOST_THREAD_IS_LOCKED_BY_THIS_THREAD_HPP
+
+#include <boost/thread/detail/config.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ template <typename Lockable>
+ class testable_mutex;
+
+ /**
+ * Overloaded function used to check if the mutex is locked when it is testable and do nothing otherwise.
+ *
+ * This function is used usually to assert the pre-condition when the function can only be called when the mutex
+ * must be locked by the current thread.
+ */
+ template <typename Lockable>
+ bool is_locked_by_this_thread(testable_mutex<Lockable> const& mtx)
+ {
+ return mtx.is_locked_by_this_thread();
+ }
+ template <typename Lockable>
+ bool is_locked_by_this_thread(Lockable const&)
+ {
+ return true;
+ }
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/latch.hpp b/src/third_party/boost-1.60.0/boost/thread/latch.hpp
new file mode 100644
index 00000000000..dc921e68fe6
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/latch.hpp
@@ -0,0 +1,170 @@
+// Distributed under the 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
+
+#ifndef BOOST_THREAD_LATCH_HPP
+#define BOOST_THREAD_LATCH_HPP
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/detail/delete.hpp>
+#include <boost/thread/detail/counter.hpp>
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/condition_variable.hpp>
+#include <boost/chrono/duration.hpp>
+#include <boost/chrono/time_point.hpp>
+#include <boost/assert.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ class latch
+ {
+ /// @Requires: count_ must be greater than 0
+ /// Effect: Decrement the count. Unlocks the lock and notify anyone waiting if we reached zero.
+ /// Returns: true if count_ reached the value 0.
+ /// @ThreadSafe ensured by the @c lk parameter
+ bool count_down(unique_lock<mutex> &)
+ /// pre_condition (count_ > 0)
+ {
+ BOOST_ASSERT(count_ > 0);
+ if (--count_ == 0)
+ {
+ ++generation_;
+ //lk.unlock();
+ cond_.notify_all();
+ return true;
+ }
+ return false;
+ }
+ /// Effect: Decrement the count is > 0. Unlocks the lock notify anyone waiting if we reached zero.
+ /// Returns: true if count_ is 0.
+ /// @ThreadSafe ensured by the @c lk parameter
+ bool try_count_down(unique_lock<mutex> &lk)
+ {
+ if (count_ > 0)
+ {
+ return count_down(lk);
+ }
+ return true;
+ }
+ public:
+ BOOST_THREAD_NO_COPYABLE( latch)
+
+ /// Constructs a latch with a given count.
+ latch(std::size_t count) :
+ count_(count), generation_(0)
+ {
+ }
+
+ /// Destructor
+ /// Precondition: No threads are waiting or invoking count_down on @c *this.
+
+ ~latch()
+ {
+
+ }
+
+ /// Blocks until the latch has counted down to zero.
+ void wait()
+ {
+ boost::unique_lock<boost::mutex> lk(mutex_);
+ if (count_ == 0) return;
+ std::size_t generation(generation_);
+ cond_.wait(lk, detail::not_equal(generation, generation_));
+ }
+
+ /// @return true if the internal counter is already 0, false otherwise
+ bool try_wait()
+ {
+ boost::unique_lock<boost::mutex> lk(mutex_);
+ return (count_ == 0);
+ }
+
+ /// try to wait for a specified amount of time is elapsed.
+ /// @return whether there is a timeout or not.
+ template <class Rep, class Period>
+ cv_status wait_for(const chrono::duration<Rep, Period>& rel_time)
+ {
+ boost::unique_lock<boost::mutex> lk(mutex_);
+ if (count_ == 0) return cv_status::no_timeout;
+ std::size_t generation(generation_);
+ return cond_.wait_for(lk, rel_time, detail::not_equal(generation, generation_))
+ ? cv_status::no_timeout
+ : cv_status::timeout;
+ }
+
+ /// try to wait until the specified time_point is reached
+ /// @return whether there were a timeout or not.
+ template <class Clock, class Duration>
+ cv_status wait_until(const chrono::time_point<Clock, Duration>& abs_time)
+ {
+ boost::unique_lock<boost::mutex> lk(mutex_);
+ if (count_ == 0) return cv_status::no_timeout;
+ std::size_t generation(generation_);
+ return cond_.wait_until(lk, abs_time, detail::not_equal(generation, generation_))
+ ? cv_status::no_timeout
+ : cv_status::timeout;
+ }
+
+ /// Decrement the count and notify anyone waiting if we reach zero.
+ /// @Requires count must be greater than 0
+ void count_down()
+ {
+ boost::unique_lock<boost::mutex> lk(mutex_);
+ count_down(lk);
+ }
+ /// Effect: Decrement the count if it is > 0 and notify anyone waiting if we reached zero.
+ /// Returns: true if count_ was 0 or reached 0.
+ bool try_count_down()
+ {
+ boost::unique_lock<boost::mutex> lk(mutex_);
+ return try_count_down(lk);
+ }
+ void signal()
+ {
+ count_down();
+ }
+
+ /// Decrement the count and notify anyone waiting if we reach zero.
+ /// Blocks until the latch has counted down to zero.
+ /// @Requires count must be greater than 0
+ void count_down_and_wait()
+ {
+ boost::unique_lock<boost::mutex> lk(mutex_);
+ std::size_t generation(generation_);
+ if (count_down(lk))
+ {
+ return;
+ }
+ cond_.wait(lk, detail::not_equal(generation, generation_));
+ }
+ void sync()
+ {
+ count_down_and_wait();
+ }
+
+ /// Reset the counter
+ /// #Requires This method may only be invoked when there are no other threads currently inside the count_down_and_wait() method.
+ void reset(std::size_t count)
+ {
+ boost::lock_guard<boost::mutex> lk(mutex_);
+ //BOOST_ASSERT(count_ == 0);
+ count_ = count;
+ }
+
+ private:
+ mutex mutex_;
+ condition_variable cond_;
+ std::size_t count_;
+ std::size_t generation_;
+ };
+
+} // namespace boost
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/lock_algorithms.hpp b/src/third_party/boost-1.60.0/boost/thread/lock_algorithms.hpp
new file mode 100644
index 00000000000..7a55f92a289
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/lock_algorithms.hpp
@@ -0,0 +1,468 @@
+// Distributed under the 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 2007 Anthony Williams
+// (C) Copyright 2011-2012 Vicente J. Botet Escriba
+
+#ifndef BOOST_THREAD_LOCK_ALGORITHMS_HPP
+#define BOOST_THREAD_LOCK_ALGORITHMS_HPP
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/lockable_traits.hpp>
+
+#include <algorithm>
+#include <iterator>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ namespace detail
+ {
+ template <typename MutexType1, typename MutexType2>
+ unsigned try_lock_internal(MutexType1& m1, MutexType2& m2)
+ {
+ boost::unique_lock<MutexType1> l1(m1, boost::try_to_lock);
+ if (!l1)
+ {
+ return 1;
+ }
+ if (!m2.try_lock())
+ {
+ return 2;
+ }
+ l1.release();
+ return 0;
+ }
+
+ template <typename MutexType1, typename MutexType2, typename MutexType3>
+ unsigned try_lock_internal(MutexType1& m1, MutexType2& m2, MutexType3& m3)
+ {
+ boost::unique_lock<MutexType1> l1(m1, boost::try_to_lock);
+ if (!l1)
+ {
+ return 1;
+ }
+ if (unsigned const failed_lock=try_lock_internal(m2,m3))
+ {
+ return failed_lock + 1;
+ }
+ l1.release();
+ return 0;
+ }
+
+ template <typename MutexType1, typename MutexType2, typename MutexType3, typename MutexType4>
+ unsigned try_lock_internal(MutexType1& m1, MutexType2& m2, MutexType3& m3, MutexType4& m4)
+ {
+ boost::unique_lock<MutexType1> l1(m1, boost::try_to_lock);
+ if (!l1)
+ {
+ return 1;
+ }
+ if (unsigned const failed_lock=try_lock_internal(m2,m3,m4))
+ {
+ return failed_lock + 1;
+ }
+ l1.release();
+ return 0;
+ }
+
+ template <typename MutexType1, typename MutexType2, typename MutexType3, typename MutexType4, typename MutexType5>
+ unsigned try_lock_internal(MutexType1& m1, MutexType2& m2, MutexType3& m3, MutexType4& m4, MutexType5& m5)
+ {
+ boost::unique_lock<MutexType1> l1(m1, boost::try_to_lock);
+ if (!l1)
+ {
+ return 1;
+ }
+ if (unsigned const failed_lock=try_lock_internal(m2,m3,m4,m5))
+ {
+ return failed_lock + 1;
+ }
+ l1.release();
+ return 0;
+ }
+
+ template <typename MutexType1, typename MutexType2>
+ unsigned lock_helper(MutexType1& m1, MutexType2& m2)
+ {
+ boost::unique_lock<MutexType1> l1(m1);
+ if (!m2.try_lock())
+ {
+ return 1;
+ }
+ l1.release();
+ return 0;
+ }
+
+ template <typename MutexType1, typename MutexType2, typename MutexType3>
+ unsigned lock_helper(MutexType1& m1, MutexType2& m2, MutexType3& m3)
+ {
+ boost::unique_lock<MutexType1> l1(m1);
+ if (unsigned const failed_lock=try_lock_internal(m2,m3))
+ {
+ return failed_lock;
+ }
+ l1.release();
+ return 0;
+ }
+
+ template <typename MutexType1, typename MutexType2, typename MutexType3, typename MutexType4>
+ unsigned lock_helper(MutexType1& m1, MutexType2& m2, MutexType3& m3, MutexType4& m4)
+ {
+ boost::unique_lock<MutexType1> l1(m1);
+ if (unsigned const failed_lock=try_lock_internal(m2,m3,m4))
+ {
+ return failed_lock;
+ }
+ l1.release();
+ return 0;
+ }
+
+ template <typename MutexType1, typename MutexType2, typename MutexType3, typename MutexType4, typename MutexType5>
+ unsigned lock_helper(MutexType1& m1, MutexType2& m2, MutexType3& m3, MutexType4& m4, MutexType5& m5)
+ {
+ boost::unique_lock<MutexType1> l1(m1);
+ if (unsigned const failed_lock=try_lock_internal(m2,m3,m4,m5))
+ {
+ return failed_lock;
+ }
+ l1.release();
+ return 0;
+ }
+ }
+
+ namespace detail
+ {
+ template <bool x>
+ struct is_mutex_type_wrapper
+ {
+ };
+
+ template <typename MutexType1, typename MutexType2>
+ void lock_impl(MutexType1& m1, MutexType2& m2, is_mutex_type_wrapper<true> )
+ {
+ unsigned const lock_count = 2;
+ unsigned lock_first = 0;
+ for (;;)
+ {
+ switch (lock_first)
+ {
+ case 0:
+ lock_first = detail::lock_helper(m1, m2);
+ if (!lock_first) return;
+ break;
+ case 1:
+ lock_first = detail::lock_helper(m2, m1);
+ if (!lock_first) return;
+ lock_first = (lock_first + 1) % lock_count;
+ break;
+ }
+ }
+ }
+
+ template <typename Iterator>
+ void lock_impl(Iterator begin, Iterator end, is_mutex_type_wrapper<false> );
+ }
+
+ template <typename MutexType1, typename MutexType2>
+ void lock(MutexType1& m1, MutexType2& m2)
+ {
+ detail::lock_impl(m1, m2, detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
+ }
+
+ template <typename MutexType1, typename MutexType2>
+ void lock(const MutexType1& m1, MutexType2& m2)
+ {
+ detail::lock_impl(m1, m2, detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
+ }
+
+ template <typename MutexType1, typename MutexType2>
+ void lock(MutexType1& m1, const MutexType2& m2)
+ {
+ detail::lock_impl(m1, m2, detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
+ }
+
+ template <typename MutexType1, typename MutexType2>
+ void lock(const MutexType1& m1, const MutexType2& m2)
+ {
+ detail::lock_impl(m1, m2, detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
+ }
+
+ template <typename MutexType1, typename MutexType2, typename MutexType3>
+ void lock(MutexType1& m1, MutexType2& m2, MutexType3& m3)
+ {
+ unsigned const lock_count = 3;
+ unsigned lock_first = 0;
+ for (;;)
+ {
+ switch (lock_first)
+ {
+ case 0:
+ lock_first = detail::lock_helper(m1, m2, m3);
+ if (!lock_first) return;
+ break;
+ case 1:
+ lock_first = detail::lock_helper(m2, m3, m1);
+ if (!lock_first) return;
+ lock_first = (lock_first + 1) % lock_count;
+ break;
+ case 2:
+ lock_first = detail::lock_helper(m3, m1, m2);
+ if (!lock_first) return;
+ lock_first = (lock_first + 2) % lock_count;
+ break;
+ }
+ }
+ }
+
+ template <typename MutexType1, typename MutexType2, typename MutexType3, typename MutexType4>
+ void lock(MutexType1& m1, MutexType2& m2, MutexType3& m3, MutexType4& m4)
+ {
+ unsigned const lock_count = 4;
+ unsigned lock_first = 0;
+ for (;;)
+ {
+ switch (lock_first)
+ {
+ case 0:
+ lock_first = detail::lock_helper(m1, m2, m3, m4);
+ if (!lock_first) return;
+ break;
+ case 1:
+ lock_first = detail::lock_helper(m2, m3, m4, m1);
+ if (!lock_first) return;
+ lock_first = (lock_first + 1) % lock_count;
+ break;
+ case 2:
+ lock_first = detail::lock_helper(m3, m4, m1, m2);
+ if (!lock_first) return;
+ lock_first = (lock_first + 2) % lock_count;
+ break;
+ case 3:
+ lock_first = detail::lock_helper(m4, m1, m2, m3);
+ if (!lock_first) return;
+ lock_first = (lock_first + 3) % lock_count;
+ break;
+ }
+ }
+ }
+
+ template <typename MutexType1, typename MutexType2, typename MutexType3, typename MutexType4, typename MutexType5>
+ void lock(MutexType1& m1, MutexType2& m2, MutexType3& m3, MutexType4& m4, MutexType5& m5)
+ {
+ unsigned const lock_count = 5;
+ unsigned lock_first = 0;
+ for (;;)
+ {
+ switch (lock_first)
+ {
+ case 0:
+ lock_first = detail::lock_helper(m1, m2, m3, m4, m5);
+ if (!lock_first) return;
+ break;
+ case 1:
+ lock_first = detail::lock_helper(m2, m3, m4, m5, m1);
+ if (!lock_first) return;
+ lock_first = (lock_first + 1) % lock_count;
+ break;
+ case 2:
+ lock_first = detail::lock_helper(m3, m4, m5, m1, m2);
+ if (!lock_first) return;
+ lock_first = (lock_first + 2) % lock_count;
+ break;
+ case 3:
+ lock_first = detail::lock_helper(m4, m5, m1, m2, m3);
+ if (!lock_first) return;
+ lock_first = (lock_first + 3) % lock_count;
+ break;
+ case 4:
+ lock_first = detail::lock_helper(m5, m1, m2, m3, m4);
+ if (!lock_first) return;
+ lock_first = (lock_first + 4) % lock_count;
+ break;
+ }
+ }
+ }
+
+ namespace detail
+ {
+ template <typename Mutex, bool x = is_mutex_type<Mutex>::value>
+ struct try_lock_impl_return
+ {
+ typedef int type;
+ };
+
+ template <typename Iterator>
+ struct try_lock_impl_return<Iterator, false>
+ {
+ typedef Iterator type;
+ };
+
+ template <typename MutexType1, typename MutexType2>
+ int try_lock_impl(MutexType1& m1, MutexType2& m2, is_mutex_type_wrapper<true> )
+ {
+ return ((int) detail::try_lock_internal(m1, m2)) - 1;
+ }
+
+ template <typename Iterator>
+ Iterator try_lock_impl(Iterator begin, Iterator end, is_mutex_type_wrapper<false> );
+ }
+
+ template <typename MutexType1, typename MutexType2>
+ typename detail::try_lock_impl_return<MutexType1>::type try_lock(MutexType1& m1, MutexType2& m2)
+ {
+ return detail::try_lock_impl(m1, m2, detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
+ }
+
+ template <typename MutexType1, typename MutexType2>
+ typename detail::try_lock_impl_return<MutexType1>::type try_lock(const MutexType1& m1, MutexType2& m2)
+ {
+ return detail::try_lock_impl(m1, m2, detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
+ }
+
+ template <typename MutexType1, typename MutexType2>
+ typename detail::try_lock_impl_return<MutexType1>::type try_lock(MutexType1& m1, const MutexType2& m2)
+ {
+ return detail::try_lock_impl(m1, m2, detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
+ }
+
+ template <typename MutexType1, typename MutexType2>
+ typename detail::try_lock_impl_return<MutexType1>::type try_lock(const MutexType1& m1, const MutexType2& m2)
+ {
+ return detail::try_lock_impl(m1, m2, detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
+ }
+
+ template <typename MutexType1, typename MutexType2, typename MutexType3>
+ int try_lock(MutexType1& m1, MutexType2& m2, MutexType3& m3)
+ {
+ return ((int) detail::try_lock_internal(m1, m2, m3)) - 1;
+ }
+
+ template <typename MutexType1, typename MutexType2, typename MutexType3, typename MutexType4>
+ int try_lock(MutexType1& m1, MutexType2& m2, MutexType3& m3, MutexType4& m4)
+ {
+ return ((int) detail::try_lock_internal(m1, m2, m3, m4)) - 1;
+ }
+
+ template <typename MutexType1, typename MutexType2, typename MutexType3, typename MutexType4, typename MutexType5>
+ int try_lock(MutexType1& m1, MutexType2& m2, MutexType3& m3, MutexType4& m4, MutexType5& m5)
+ {
+ return ((int) detail::try_lock_internal(m1, m2, m3, m4, m5)) - 1;
+ }
+
+ namespace detail
+ {
+ template <typename Iterator>
+ struct range_lock_guard
+ {
+ Iterator begin;
+ Iterator end;
+
+ range_lock_guard(Iterator begin_, Iterator end_) :
+ begin(begin_), end(end_)
+ {
+ boost::lock(begin, end);
+ }
+
+ void release()
+ {
+ begin = end;
+ }
+
+ ~range_lock_guard()
+ {
+ for (; begin != end; ++begin)
+ {
+ begin->unlock();
+ }
+ }
+ };
+
+ template <typename Iterator>
+ Iterator try_lock_impl(Iterator begin, Iterator end, is_mutex_type_wrapper<false> )
+
+ {
+ if (begin == end)
+ {
+ return end;
+ }
+ typedef typename std::iterator_traits<Iterator>::value_type lock_type;
+ unique_lock<lock_type> guard(*begin, try_to_lock);
+
+ if (!guard.owns_lock())
+ {
+ return begin;
+ }
+ Iterator const failed = boost::try_lock(++begin, end);
+ if (failed == end)
+ {
+ guard.release();
+ }
+
+ return failed;
+ }
+ }
+
+ namespace detail
+ {
+ template <typename Iterator>
+ void lock_impl(Iterator begin, Iterator end, is_mutex_type_wrapper<false> )
+ {
+ typedef typename std::iterator_traits<Iterator>::value_type lock_type;
+
+ if (begin == end)
+ {
+ return;
+ }
+ bool start_with_begin = true;
+ Iterator second = begin;
+ ++second;
+ Iterator next = second;
+
+ for (;;)
+ {
+ unique_lock<lock_type> begin_lock(*begin, defer_lock);
+ if (start_with_begin)
+ {
+ begin_lock.lock();
+ Iterator const failed_lock = boost::try_lock(next, end);
+ if (failed_lock == end)
+ {
+ begin_lock.release();
+ return;
+ }
+ start_with_begin = false;
+ next = failed_lock;
+ }
+ else
+ {
+ detail::range_lock_guard<Iterator> guard(next, end);
+ if (begin_lock.try_lock())
+ {
+ Iterator const failed_lock = boost::try_lock(second, next);
+ if (failed_lock == next)
+ {
+ begin_lock.release();
+ guard.release();
+ return;
+ }
+ start_with_begin = false;
+ next = failed_lock;
+ }
+ else
+ {
+ start_with_begin = true;
+ next = second;
+ }
+ }
+ }
+ }
+
+ }
+
+}
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/lock_concepts.hpp b/src/third_party/boost-1.60.0/boost/thread/lock_concepts.hpp
new file mode 100644
index 00000000000..d96c3dc1b96
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/lock_concepts.hpp
@@ -0,0 +1,197 @@
+// (C) Copyright 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)
+
+#ifndef BOOST_THREAD_LOCK_CONCEPTS_HPP
+#define BOOST_THREAD_LOCK_CONCEPTS_HPP
+
+#include <boost/thread/lock_traits.hpp>
+#include <boost/thread/lock_options.hpp>
+#include <boost/thread/lockable_concepts.hpp>
+#include <boost/thread/exceptions.hpp>
+#include <boost/thread/detail/move.hpp>
+
+#include <boost/chrono/chrono.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/static_assert.hpp>
+
+namespace boost
+{
+
+ /**
+ * BasicLock object supports the basic features
+ * required to delimit a critical region
+ * Supports the basic lock, unlock and try_lock functions and
+ * defines the lock traits
+ */
+
+ template <typename Lk>
+ struct BasicLock
+ {
+ typedef typename Lk::mutex_type mutex_type;
+ void cvt_mutex_ptr(mutex_type*) {}
+ BOOST_CONCEPT_ASSERT(( BasicLockable<mutex_type> ));
+
+ BOOST_CONCEPT_USAGE(BasicLock)
+ {
+ const Lk l1(mtx);
+ Lk l2(mtx, defer_lock);
+ Lk l3(mtx, adopt_lock);
+ Lk l4(( Lk()));
+ Lk l5(( boost::move(l2)));
+ cvt_mutex_ptr(l1.mutex());
+ if (l1.owns_lock()) return;
+ if (l1) return;
+ if (!l1) return;
+
+ l2.lock();
+ l2.unlock();
+ l2.release();
+
+ }
+ BasicLock() :
+ mtx(*static_cast<mutex_type*>(0))
+ {}
+ private:
+ BasicLock operator=(BasicLock const&);
+ mutex_type& mtx;
+ }
+ ;
+
+ template <typename Lk>
+ struct Lock
+ {
+ BOOST_CONCEPT_ASSERT(( BasicLock<Lk> ));
+ typedef typename Lk::mutex_type mutex_type;
+ BOOST_CONCEPT_ASSERT(( Lockable<mutex_type> ));
+
+ BOOST_CONCEPT_USAGE(Lock)
+ {
+ Lk l1(mtx, try_to_lock);
+ if (l1.try_lock()) return;
+ }
+ Lock() :
+ mtx(*static_cast<mutex_type*>(0))
+ {}
+ private:
+ Lock operator=(Lock const&);
+ mutex_type& mtx;
+ };
+
+ template <typename Lk>
+ struct TimedLock
+ {
+ BOOST_CONCEPT_ASSERT(( Lock<Lk> ));
+ typedef typename Lk::mutex_type mutex_type;
+ BOOST_CONCEPT_ASSERT(( TimedLockable<mutex_type> ));
+
+ BOOST_CONCEPT_USAGE(TimedLock)
+ {
+ const Lk l1(mtx, t);
+ Lk l2(mtx, d);
+ if (l1.try_lock_until(t)) return;
+ if (l1.try_lock_for(d)) return;
+ }
+ TimedLock() :
+ mtx(*static_cast<mutex_type*>(0))
+ {}
+ private:
+ TimedLock operator=(TimedLock const&);
+ mutex_type& mtx;
+ boost::chrono::system_clock::time_point t;
+ boost::chrono::system_clock::duration d;
+ };
+
+ template <typename Lk>
+ struct UniqueLock
+ {
+ BOOST_CONCEPT_ASSERT(( TimedLock<Lk> ));
+ typedef typename Lk::mutex_type mutex_type;
+
+ BOOST_CONCEPT_USAGE(UniqueLock)
+ {
+
+ }
+ UniqueLock() :
+ mtx(*static_cast<mutex_type*>(0))
+ {}
+ private:
+ UniqueLock operator=(UniqueLock const&);
+ mutex_type& mtx;
+ };
+
+ template <typename Lk>
+ struct SharedLock
+ {
+ BOOST_CONCEPT_ASSERT(( TimedLock<Lk> ));
+ typedef typename Lk::mutex_type mutex_type;
+
+ BOOST_CONCEPT_USAGE(SharedLock)
+ {
+ }
+ SharedLock() :
+ mtx(*static_cast<mutex_type*>(0))
+ {}
+ private:
+ SharedLock operator=(SharedLock const&);
+ mutex_type& mtx;
+
+ };
+
+ template <typename Lk>
+ struct UpgradeLock
+ {
+ BOOST_CONCEPT_ASSERT(( SharedLock<Lk> ));
+ typedef typename Lk::mutex_type mutex_type;
+
+ BOOST_CONCEPT_USAGE(UpgradeLock)
+ {
+ }
+ UpgradeLock() :
+ mtx(*static_cast<mutex_type*>(0))
+ {}
+ private:
+ UpgradeLock operator=(UpgradeLock const&);
+ mutex_type& mtx;
+ };
+
+ /**
+ * An StrictLock is a scoped lock guard ensuring the mutex is locked on the
+ * scope of the lock, by locking the mutex on construction and unlocking it on
+ * destruction.
+ *
+ * Essentially, a StrictLock's role is only to live on the stack as an
+ * automatic variable. strict_lock must adhere to a non-copy and non-alias
+ * policy. StrictLock disables copying by making the copy constructor and the
+ * assignment operator private. While we're at it, let's disable operator new
+ * and operator delete; strict locks are not intended to be allocated on the
+ * heap. StrictLock avoids aliasing by using a slightly less orthodox and
+ * less well-known technique: disable address taking.
+ */
+
+ template <typename Lk>
+ struct StrictLock
+ {
+ typedef typename Lk::mutex_type mutex_type;
+ BOOST_CONCEPT_ASSERT(( BasicLockable<mutex_type> ));
+ BOOST_STATIC_ASSERT(( is_strict_lock<Lk>::value ));
+
+ BOOST_CONCEPT_USAGE( StrictLock)
+ {
+ if (l1.owns_lock(&mtx)) return;
+ }
+ StrictLock() :
+ l1(*static_cast<Lk*>(0)),
+ mtx(*static_cast<mutex_type*>(0))
+ {}
+ private:
+ StrictLock operator=(StrictLock const&);
+
+ Lk const& l1;
+ mutex_type const& mtx;
+
+ };
+
+}
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/lock_factories.hpp b/src/third_party/boost-1.60.0/boost/thread/lock_factories.hpp
new file mode 100644
index 00000000000..523b90a5eac
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/lock_factories.hpp
@@ -0,0 +1,78 @@
+// Distributed under the 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 2012 Vicente J. Botet Escriba
+
+#ifndef BOOST_THREAD_LOCK_FACTORIES_HPP
+#define BOOST_THREAD_LOCK_FACTORIES_HPP
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/lock_algorithms.hpp>
+#if ! defined(BOOST_THREAD_NO_MAKE_UNIQUE_LOCKS)
+#include <tuple> // todo change to <boost/tuple.hpp> once Boost.Tuple or Boost.Fusion provides Move semantics.
+#endif
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+
+ template <typename Lockable>
+ unique_lock<Lockable> make_unique_lock(Lockable& mtx)
+ {
+ return unique_lock<Lockable> (mtx);
+ }
+
+ template <typename Lockable>
+ unique_lock<Lockable> make_unique_lock(Lockable& mtx, adopt_lock_t)
+ {
+ return unique_lock<Lockable> (mtx, adopt_lock);
+ }
+
+ template <typename Lockable>
+ unique_lock<Lockable> make_unique_lock(Lockable& mtx, defer_lock_t)
+ {
+ return unique_lock<Lockable> (mtx, defer_lock);
+ }
+
+ template <typename Lockable>
+ unique_lock<Lockable> make_unique_lock(Lockable& mtx, try_to_lock_t)
+ {
+ return unique_lock<Lockable> (mtx, try_to_lock);
+ }
+#if ! defined(BOOST_THREAD_NO_MAKE_UNIQUE_LOCKS)
+
+#if ! defined BOOST_NO_CXX11_VARIADIC_TEMPLATES
+ template <typename ...Lockable>
+ std::tuple<unique_lock<Lockable> ...> make_unique_locks(Lockable& ...mtx)
+ {
+ boost::lock(mtx...);
+ return std::tuple<unique_lock<Lockable> ...>(unique_lock<Lockable>(mtx, adopt_lock)...);
+ }
+#else
+ template <typename L1, typename L2>
+ std::tuple<unique_lock<L1>, unique_lock<L2> > make_unique_locks(L1& m1, L2& m2)
+ {
+ boost::lock(m1, m2);
+ return std::tuple<unique_lock<L1>,unique_lock<L2> >(
+ unique_lock<L1>(m1, adopt_lock),
+ unique_lock<L2>(m2, adopt_lock)
+ );
+ }
+ template <typename L1, typename L2, typename L3>
+ std::tuple<unique_lock<L1>, unique_lock<L2>, unique_lock<L3> > make_unique_locks(L1& m1, L2& m2, L3& m3)
+ {
+ boost::lock(m1, m2, m3);
+ return std::tuple<unique_lock<L1>,unique_lock<L2>,unique_lock<L3> >(
+ unique_lock<L1>(m1, adopt_lock),
+ unique_lock<L2>(m2, adopt_lock),
+ unique_lock<L3>(m3, adopt_lock)
+ );
+ }
+
+#endif
+#endif
+
+}
+
+#include <boost/config/abi_suffix.hpp>
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/lock_guard.hpp b/src/third_party/boost-1.60.0/boost/thread/lock_guard.hpp
new file mode 100644
index 00000000000..4c2908af43f
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/lock_guard.hpp
@@ -0,0 +1,88 @@
+// Distributed under the 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 2007 Anthony Williams
+// (C) Copyright 2011-2012 Vicente J. Botet Escriba
+
+#ifndef BOOST_THREAD_LOCK_GUARD_HPP
+#define BOOST_THREAD_LOCK_GUARD_HPP
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/detail/delete.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/detail/lockable_wrapper.hpp>
+#include <boost/thread/lock_options.hpp>
+#if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
+#include <boost/thread/is_locked_by_this_thread.hpp>
+#include <boost/assert.hpp>
+#endif
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+
+ template <typename Mutex>
+ class lock_guard
+ {
+ private:
+ Mutex& m;
+
+ public:
+ typedef Mutex mutex_type;
+ BOOST_THREAD_NO_COPYABLE( lock_guard )
+
+ explicit lock_guard(Mutex& m_) :
+ m(m_)
+ {
+ m.lock();
+ }
+
+ lock_guard(Mutex& m_, adopt_lock_t) :
+ m(m_)
+ {
+#if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
+ BOOST_ASSERT(is_locked_by_this_thread(m));
+#endif
+ }
+
+#if ! defined BOOST_THREAD_NO_CXX11_HDR_INITIALIZER_LIST
+ lock_guard(std::initializer_list<thread_detail::lockable_wrapper<Mutex> > l_) :
+ m(*(const_cast<thread_detail::lockable_wrapper<Mutex>*>(l_.begin())->m))
+ {
+ m.lock();
+ }
+
+ lock_guard(std::initializer_list<thread_detail::lockable_adopt_wrapper<Mutex> > l_) :
+ m(*(const_cast<thread_detail::lockable_adopt_wrapper<Mutex>*>(l_.begin())->m))
+ {
+#if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
+ BOOST_ASSERT(is_locked_by_this_thread(m));
+#endif
+ }
+
+#endif
+ ~lock_guard()
+ {
+ m.unlock();
+ }
+ };
+
+
+#if ! defined BOOST_THREAD_NO_MAKE_LOCK_GUARD
+ template <typename Lockable>
+ lock_guard<Lockable> make_lock_guard(Lockable& mtx)
+ {
+ return { thread_detail::lockable_wrapper<Lockable>(mtx) };
+ }
+ template <typename Lockable>
+ lock_guard<Lockable> make_lock_guard(Lockable& mtx, adopt_lock_t)
+ {
+ return { thread_detail::lockable_adopt_wrapper<Lockable>(mtx) };
+ }
+#endif
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/lock_options.hpp b/src/third_party/boost-1.60.0/boost/thread/lock_options.hpp
new file mode 100644
index 00000000000..68899ca89fe
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/lock_options.hpp
@@ -0,0 +1,31 @@
+// Distributed under the 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 2007 Anthony Williams
+// (C) Copyright 2011-2012 Vicente J. Botet Escriba
+
+#ifndef BOOST_THREAD_LOCK_OPTIONS_HPP
+#define BOOST_THREAD_LOCK_OPTIONS_HPP
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ struct defer_lock_t
+ {
+ };
+ struct try_to_lock_t
+ {
+ };
+ struct adopt_lock_t
+ {
+ };
+
+ BOOST_CONSTEXPR_OR_CONST defer_lock_t defer_lock = {};
+ BOOST_CONSTEXPR_OR_CONST try_to_lock_t try_to_lock = {};
+ BOOST_CONSTEXPR_OR_CONST adopt_lock_t adopt_lock = {};
+
+}
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/lock_traits.hpp b/src/third_party/boost-1.60.0/boost/thread/lock_traits.hpp
new file mode 100644
index 00000000000..e45d8229831
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/lock_traits.hpp
@@ -0,0 +1,45 @@
+// Distributed under the 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 2009-2012 Vicente J. Botet Escriba
+
+#ifndef BOOST_THREAD_LOCK_TRAITS_HPP
+#define BOOST_THREAD_LOCK_TRAITS_HPP
+
+#include <boost/thread/detail/config.hpp>
+//#include <boost/thread/detail/move.hpp>
+//#include <boost/thread/exceptions.hpp>
+//
+//#ifdef BOOST_THREAD_USES_CHRONO
+//#include <boost/chrono/time_point.hpp>
+//#include <boost/chrono/duration.hpp>
+//#endif
+
+#include <boost/type_traits/integral_constant.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+
+/**
+ * An strict lock is a lock ensuring the mutex is locked on the scope of the lock
+ * There is no single way to define a strict lock as the strict_lock and
+ * nesteed_strict_lock shows. So we need a metafunction that states if a
+ * lock is a strict lock "sur parole".
+ */
+
+template <typename Lock>
+struct is_strict_lock_sur_parolle : false_type {};
+
+
+template <typename Lock>
+struct is_strict_lock_sur_parole : is_strict_lock_sur_parolle<Lock> {};
+
+template <typename Lock>
+struct is_strict_lock : is_strict_lock_sur_parole<Lock> {};
+
+}
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/lock_types.hpp b/src/third_party/boost-1.60.0/boost/thread/lock_types.hpp
new file mode 100644
index 00000000000..2b73edfb02a
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/lock_types.hpp
@@ -0,0 +1,1230 @@
+// Distributed under the 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 2007 Anthony Williams
+// (C) Copyright 2011-2012 Vicente J. Botet Escriba
+
+#ifndef BOOST_THREAD_LOCK_TYPES_HPP
+#define BOOST_THREAD_LOCK_TYPES_HPP
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/exceptions.hpp>
+#include <boost/thread/lock_options.hpp>
+#include <boost/thread/lockable_traits.hpp>
+#if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
+#include <boost/thread/is_locked_by_this_thread.hpp>
+#endif
+#include <boost/thread/thread_time.hpp>
+
+#include <boost/assert.hpp>
+#ifdef BOOST_THREAD_USES_CHRONO
+#include <boost/chrono/time_point.hpp>
+#include <boost/chrono/duration.hpp>
+#endif
+#include <boost/detail/workaround.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ struct xtime;
+
+ template <typename Mutex>
+ class shared_lock;
+
+ template <typename Mutex>
+ class upgrade_lock;
+
+ template <typename Mutex>
+ class unique_lock;
+
+ namespace detail
+ {
+ template <typename Mutex>
+ class try_lock_wrapper;
+ }
+
+#ifdef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
+ namespace sync
+ {
+ template<typename T>
+ struct is_basic_lockable<unique_lock<T> >
+ {
+ BOOST_STATIC_CONSTANT(bool, value = true);
+ };
+ template<typename T>
+ struct is_lockable<unique_lock<T> >
+ {
+ BOOST_STATIC_CONSTANT(bool, value = true);
+ };
+
+ template<typename T>
+ struct is_basic_lockable<shared_lock<T> >
+ {
+ BOOST_STATIC_CONSTANT(bool, value = true);
+ };
+ template<typename T>
+ struct is_lockable<shared_lock<T> >
+ {
+ BOOST_STATIC_CONSTANT(bool, value = true);
+ };
+
+ template<typename T>
+ struct is_basic_lockable<upgrade_lock<T> >
+ {
+ BOOST_STATIC_CONSTANT(bool, value = true);
+ };
+ template<typename T>
+ struct is_lockable<upgrade_lock<T> >
+ {
+ BOOST_STATIC_CONSTANT(bool, value = true);
+ };
+
+ template<typename T>
+ struct is_basic_lockable<detail::try_lock_wrapper<T> >
+ {
+ BOOST_STATIC_CONSTANT(bool, value = true);
+ };
+ template<typename T>
+ struct is_lockable<detail::try_lock_wrapper<T> >
+ {
+ BOOST_STATIC_CONSTANT(bool, value = true);
+ };
+ }
+#endif
+
+
+ template <typename Mutex>
+ class unique_lock
+ {
+ private:
+ Mutex* m;
+ bool is_locked;
+
+ private:
+ explicit unique_lock(upgrade_lock<Mutex>&);
+ unique_lock& operator=(upgrade_lock<Mutex>& other);
+ public:
+ typedef Mutex mutex_type;
+ BOOST_THREAD_MOVABLE_ONLY( unique_lock)
+
+#if 0 // This should not be needed anymore. Use instead BOOST_THREAD_MAKE_RV_REF.
+#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
+ unique_lock(const volatile unique_lock&);
+#endif
+#endif
+ unique_lock()BOOST_NOEXCEPT :
+ m(0),is_locked(false)
+ {}
+
+ explicit unique_lock(Mutex& m_) :
+ m(&m_), is_locked(false)
+ {
+ lock();
+ }
+ unique_lock(Mutex& m_, adopt_lock_t) :
+ m(&m_), is_locked(true)
+ {
+#if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
+ BOOST_ASSERT(is_locked_by_this_thread(m));
+#endif
+ }
+ unique_lock(Mutex& m_, defer_lock_t)BOOST_NOEXCEPT:
+ m(&m_),is_locked(false)
+ {}
+ unique_lock(Mutex& m_, try_to_lock_t) :
+ m(&m_), is_locked(false)
+ {
+ try_lock();
+ }
+#if defined BOOST_THREAD_USES_DATETIME
+ template<typename TimeDuration>
+ unique_lock(Mutex& m_,TimeDuration const& target_time):
+ m(&m_),is_locked(false)
+ {
+ timed_lock(target_time);
+ }
+ unique_lock(Mutex& m_,system_time const& target_time):
+ m(&m_),is_locked(false)
+ {
+ timed_lock(target_time);
+ }
+#endif
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Clock, class Duration>
+ unique_lock(Mutex& mtx, const chrono::time_point<Clock, Duration>& t)
+ : m(&mtx), is_locked(mtx.try_lock_until(t))
+ {
+ }
+ template <class Rep, class Period>
+ unique_lock(Mutex& mtx, const chrono::duration<Rep, Period>& d)
+ : m(&mtx), is_locked(mtx.try_lock_for(d))
+ {
+ }
+#endif
+
+ unique_lock(BOOST_THREAD_RV_REF(unique_lock) other) BOOST_NOEXCEPT:
+ m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)
+ {
+ BOOST_THREAD_RV(other).is_locked=false;
+ BOOST_THREAD_RV(other).m=0;
+ }
+
+ BOOST_THREAD_EXPLICIT_LOCK_CONVERSION unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other);
+
+#ifndef BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
+ //std-2104 unique_lock move-assignment should not be noexcept
+ unique_lock& operator=(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other) //BOOST_NOEXCEPT
+ {
+ unique_lock temp(::boost::move(other));
+ swap(temp);
+ return *this;
+ }
+#endif
+
+ //std-2104 unique_lock move-assignment should not be noexcept
+ unique_lock& operator=(BOOST_THREAD_RV_REF(unique_lock) other) //BOOST_NOEXCEPT
+ {
+ unique_lock temp(::boost::move(other));
+ swap(temp);
+ return *this;
+ }
+#if 0 // This should not be needed anymore. Use instead BOOST_THREAD_MAKE_RV_REF.
+#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
+ unique_lock& operator=(unique_lock<Mutex> other)
+ {
+ swap(other);
+ return *this;
+ }
+#endif // BOOST_WORKAROUND
+#endif
+
+ // Conversion from upgrade locking
+ unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<mutex_type> BOOST_THREAD_RV_REF_END ul, try_to_lock_t)
+ : m(0),is_locked(false)
+ {
+ if (BOOST_THREAD_RV(ul).owns_lock())
+ {
+ if (BOOST_THREAD_RV(ul).mutex()->try_unlock_upgrade_and_lock())
+ {
+ m = BOOST_THREAD_RV(ul).release();
+ is_locked = true;
+ }
+ }
+ else
+ {
+ m = BOOST_THREAD_RV(ul).release();
+ }
+ }
+
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Clock, class Duration>
+ unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<mutex_type> BOOST_THREAD_RV_REF_END ul,
+ const chrono::time_point<Clock, Duration>& abs_time)
+ : m(0),is_locked(false)
+ {
+ if (BOOST_THREAD_RV(ul).owns_lock())
+ {
+ if (BOOST_THREAD_RV(ul).mutex()->try_unlock_upgrade_and_lock_until(abs_time))
+ {
+ m = BOOST_THREAD_RV(ul).release();
+ is_locked = true;
+ }
+ }
+ else
+ {
+ m = BOOST_THREAD_RV(ul).release();
+ }
+ }
+
+ template <class Rep, class Period>
+ unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<mutex_type> BOOST_THREAD_RV_REF_END ul,
+ const chrono::duration<Rep, Period>& rel_time)
+ : m(0),is_locked(false)
+ {
+ if (BOOST_THREAD_RV(ul).owns_lock())
+ {
+ if (BOOST_THREAD_RV(ul).mutex()->try_unlock_upgrade_and_lock_for(rel_time))
+ {
+ m = BOOST_THREAD_RV(ul).release();
+ is_locked = true;
+ }
+ }
+ else
+ {
+ m = BOOST_THREAD_RV(ul).release();
+ }
+ }
+#endif
+
+#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+ // Conversion from shared locking
+ unique_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl, try_to_lock_t)
+ : m(0),is_locked(false)
+ {
+ if (BOOST_THREAD_RV(sl).owns_lock())
+ {
+ if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock())
+ {
+ m = BOOST_THREAD_RV(sl).release();
+ is_locked = true;
+ }
+ }
+ else
+ {
+ m = BOOST_THREAD_RV(sl).release();
+ }
+ }
+
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Clock, class Duration>
+ unique_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl,
+ const chrono::time_point<Clock, Duration>& abs_time)
+ : m(0),is_locked(false)
+ {
+ if (BOOST_THREAD_RV(sl).owns_lock())
+ {
+ if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_until(abs_time))
+ {
+ m = BOOST_THREAD_RV(sl).release();
+ is_locked = true;
+ }
+ }
+ else
+ {
+ m = BOOST_THREAD_RV(sl).release();
+ }
+ }
+
+ template <class Rep, class Period>
+ unique_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl,
+ const chrono::duration<Rep, Period>& rel_time)
+ : m(0),is_locked(false)
+ {
+ if (BOOST_THREAD_RV(sl).owns_lock())
+ {
+ if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_for(rel_time))
+ {
+ m = BOOST_THREAD_RV(sl).release();
+ is_locked = true;
+ }
+ }
+ else
+ {
+ m = BOOST_THREAD_RV(sl).release();
+ }
+ }
+#endif // BOOST_THREAD_USES_CHRONO
+#endif // BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+
+ void swap(unique_lock& other)BOOST_NOEXCEPT
+ {
+ std::swap(m,other.m);
+ std::swap(is_locked,other.is_locked);
+ }
+
+ ~unique_lock()
+ {
+ if (owns_lock())
+ {
+ m->unlock();
+ }
+ }
+ void lock()
+ {
+ if (m == 0)
+ {
+ boost::throw_exception(
+ boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex"));
+ }
+ if (owns_lock())
+ {
+ boost::throw_exception(
+ boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex"));
+ }
+ m->lock();
+ is_locked = true;
+ }
+ bool try_lock()
+ {
+ if (m == 0)
+ {
+ boost::throw_exception(
+ boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex"));
+ }
+ if (owns_lock())
+ {
+ boost::throw_exception(
+ boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex"));
+ }
+ is_locked = m->try_lock();
+ return is_locked;
+ }
+#if defined BOOST_THREAD_USES_DATETIME
+ template<typename TimeDuration>
+ bool timed_lock(TimeDuration const& relative_time)
+ {
+ if(m==0)
+ {
+ boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex"));
+ }
+ if(owns_lock())
+ {
+ boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex"));
+ }
+ is_locked=m->timed_lock(relative_time);
+ return is_locked;
+ }
+
+ bool timed_lock(::boost::system_time const& absolute_time)
+ {
+ if(m==0)
+ {
+ boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex"));
+ }
+ if(owns_lock())
+ {
+ boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex"));
+ }
+ is_locked=m->timed_lock(absolute_time);
+ return is_locked;
+ }
+ bool timed_lock(::boost::xtime const& absolute_time)
+ {
+ if(m==0)
+ {
+ boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex"));
+ }
+ if(owns_lock())
+ {
+ boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex"));
+ }
+ is_locked=m->timed_lock(absolute_time);
+ return is_locked;
+ }
+#endif
+#ifdef BOOST_THREAD_USES_CHRONO
+
+ template <class Rep, class Period>
+ bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
+ {
+ if(m==0)
+ {
+ boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex"));
+ }
+ if(owns_lock())
+ {
+ boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex"));
+ }
+ is_locked=m->try_lock_for(rel_time);
+ return is_locked;
+ }
+ template <class Clock, class Duration>
+ bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
+ {
+ if(m==0)
+ {
+ boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex"));
+ }
+ if(owns_lock())
+ {
+ boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost unique_lock owns already the mutex"));
+ }
+ is_locked=m->try_lock_until(abs_time);
+ return is_locked;
+ }
+#endif
+
+ void unlock()
+ {
+ if (m == 0)
+ {
+ boost::throw_exception(
+ boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock has no mutex"));
+ }
+ if (!owns_lock())
+ {
+ boost::throw_exception(
+ boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost unique_lock doesn't own the mutex"));
+ }
+ m->unlock();
+ is_locked = false;
+ }
+
+#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
+ typedef void (unique_lock::*bool_type)();
+ operator bool_type() const BOOST_NOEXCEPT
+ {
+ return is_locked?&unique_lock::lock:0;
+ }
+ bool operator!() const BOOST_NOEXCEPT
+ {
+ return !owns_lock();
+ }
+#else
+ explicit operator bool() const BOOST_NOEXCEPT
+ {
+ return owns_lock();
+ }
+#endif
+ bool owns_lock() const BOOST_NOEXCEPT
+ {
+ return is_locked;
+ }
+
+ Mutex* mutex() const BOOST_NOEXCEPT
+ {
+ return m;
+ }
+
+ Mutex* release()BOOST_NOEXCEPT
+ {
+ Mutex* const res=m;
+ m=0;
+ is_locked=false;
+ return res;
+ }
+
+ friend class shared_lock<Mutex> ;
+ friend class upgrade_lock<Mutex> ;
+ };
+
+ template<typename Mutex>
+ void swap(unique_lock<Mutex>& lhs, unique_lock<Mutex>& rhs)
+ BOOST_NOEXCEPT
+ {
+ lhs.swap(rhs);
+ }
+
+ BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) unique_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END
+
+ template<typename Mutex>
+ class shared_lock
+ {
+ protected:
+ Mutex* m;
+ bool is_locked;
+
+ public:
+ typedef Mutex mutex_type;
+ BOOST_THREAD_MOVABLE_ONLY(shared_lock)
+
+ shared_lock() BOOST_NOEXCEPT:
+ m(0),is_locked(false)
+ {}
+
+ explicit shared_lock(Mutex& m_):
+ m(&m_),is_locked(false)
+ {
+ lock();
+ }
+ shared_lock(Mutex& m_,adopt_lock_t):
+ m(&m_),is_locked(true)
+ {
+#if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
+ BOOST_ASSERT(is_locked_by_this_thread(m));
+#endif
+ }
+ shared_lock(Mutex& m_,defer_lock_t) BOOST_NOEXCEPT:
+ m(&m_),is_locked(false)
+ {}
+ shared_lock(Mutex& m_,try_to_lock_t):
+ m(&m_),is_locked(false)
+ {
+ try_lock();
+ }
+#if defined BOOST_THREAD_USES_DATETIME
+ shared_lock(Mutex& m_,system_time const& target_time):
+ m(&m_),is_locked(false)
+ {
+ timed_lock(target_time);
+ }
+#endif
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Clock, class Duration>
+ shared_lock(Mutex& mtx, const chrono::time_point<Clock, Duration>& t)
+ : m(&mtx), is_locked(mtx.try_lock_shared_until(t))
+ {
+ }
+ template <class Rep, class Period>
+ shared_lock(Mutex& mtx, const chrono::duration<Rep, Period>& d)
+ : m(&mtx), is_locked(mtx.try_lock_shared_for(d))
+ {
+ }
+#endif
+
+ shared_lock(BOOST_THREAD_RV_REF_BEG shared_lock<Mutex> BOOST_THREAD_RV_REF_END other) BOOST_NOEXCEPT:
+ m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)
+ {
+ BOOST_THREAD_RV(other).is_locked=false;
+ BOOST_THREAD_RV(other).m=0;
+ }
+
+ BOOST_THREAD_EXPLICIT_LOCK_CONVERSION shared_lock(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other):
+ m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)
+ {
+ if(is_locked)
+ {
+ m->unlock_and_lock_shared();
+ }
+ BOOST_THREAD_RV(other).is_locked=false;
+ BOOST_THREAD_RV(other).m=0;
+ }
+
+ BOOST_THREAD_EXPLICIT_LOCK_CONVERSION shared_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other):
+ m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)
+ {
+ if(is_locked)
+ {
+ m->unlock_upgrade_and_lock_shared();
+ }
+ BOOST_THREAD_RV(other).is_locked=false;
+ BOOST_THREAD_RV(other).m=0;
+ }
+
+ //std-2104 unique_lock move-assignment should not be noexcept
+ shared_lock& operator=(BOOST_THREAD_RV_REF_BEG shared_lock<Mutex> BOOST_THREAD_RV_REF_END other) //BOOST_NOEXCEPT
+ {
+ shared_lock temp(::boost::move(other));
+ swap(temp);
+ return *this;
+ }
+#ifndef BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
+ shared_lock& operator=(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other)
+ {
+ shared_lock temp(::boost::move(other));
+ swap(temp);
+ return *this;
+ }
+
+ shared_lock& operator=(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other)
+ {
+ shared_lock temp(::boost::move(other));
+ swap(temp);
+ return *this;
+ }
+#endif
+
+ void swap(shared_lock& other) BOOST_NOEXCEPT
+ {
+ std::swap(m,other.m);
+ std::swap(is_locked,other.is_locked);
+ }
+
+ Mutex* mutex() const BOOST_NOEXCEPT
+ {
+ return m;
+ }
+
+ Mutex* release() BOOST_NOEXCEPT
+ {
+ Mutex* const res=m;
+ m=0;
+ is_locked=false;
+ return res;
+ }
+
+ ~shared_lock()
+ {
+ if(owns_lock())
+ {
+ m->unlock_shared();
+ }
+ }
+ void lock()
+ {
+ if(m==0)
+ {
+ boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
+ }
+ if(owns_lock())
+ {
+ boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex"));
+ }
+ m->lock_shared();
+ is_locked=true;
+ }
+ bool try_lock()
+ {
+ if(m==0)
+ {
+ boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
+ }
+ if(owns_lock())
+ {
+ boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex"));
+ }
+ is_locked=m->try_lock_shared();
+ return is_locked;
+ }
+#if defined BOOST_THREAD_USES_DATETIME
+ bool timed_lock(boost::system_time const& target_time)
+ {
+ if(m==0)
+ {
+ boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
+ }
+ if(owns_lock())
+ {
+ boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex"));
+ }
+ is_locked=m->timed_lock_shared(target_time);
+ return is_locked;
+ }
+ template<typename Duration>
+ bool timed_lock(Duration const& target_time)
+ {
+ if(m==0)
+ {
+ boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
+ }
+ if(owns_lock())
+ {
+ boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex"));
+ }
+ is_locked=m->timed_lock_shared(target_time);
+ return is_locked;
+ }
+#endif
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
+ {
+ if(m==0)
+ {
+ boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
+ }
+ if(owns_lock())
+ {
+ boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex"));
+ }
+ is_locked=m->try_lock_shared_for(rel_time);
+ return is_locked;
+ }
+ template <class Clock, class Duration>
+ bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
+ {
+ if(m==0)
+ {
+ boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
+ }
+ if(owns_lock())
+ {
+ boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex"));
+ }
+ is_locked=m->try_lock_shared_until(abs_time);
+ return is_locked;
+ }
+#endif
+ void unlock()
+ {
+ if(m==0)
+ {
+ boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
+ }
+ if(!owns_lock())
+ {
+ boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock doesn't own the mutex"));
+ }
+ m->unlock_shared();
+ is_locked=false;
+ }
+
+#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
+ typedef void (shared_lock<Mutex>::*bool_type)();
+ operator bool_type() const BOOST_NOEXCEPT
+ {
+ return is_locked?&shared_lock::lock:0;
+ }
+ bool operator!() const BOOST_NOEXCEPT
+ {
+ return !owns_lock();
+ }
+#else
+ explicit operator bool() const BOOST_NOEXCEPT
+ {
+ return owns_lock();
+ }
+#endif
+ bool owns_lock() const BOOST_NOEXCEPT
+ {
+ return is_locked;
+ }
+
+ };
+
+ BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) shared_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END
+
+ template<typename Mutex>
+ void swap(shared_lock<Mutex>& lhs,shared_lock<Mutex>& rhs) BOOST_NOEXCEPT
+ {
+ lhs.swap(rhs);
+ }
+
+ template <typename Mutex>
+ class upgrade_lock
+ {
+ protected:
+ Mutex* m;
+ bool is_locked;
+
+ public:
+ typedef Mutex mutex_type;
+ BOOST_THREAD_MOVABLE_ONLY( upgrade_lock)
+
+ upgrade_lock()BOOST_NOEXCEPT:
+ m(0),is_locked(false)
+ {}
+
+ explicit upgrade_lock(Mutex& m_) :
+ m(&m_), is_locked(false)
+ {
+ lock();
+ }
+ upgrade_lock(Mutex& m_, adopt_lock_t) :
+ m(&m_), is_locked(true)
+ {
+#if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
+ BOOST_ASSERT(is_locked_by_this_thread(m));
+#endif
+ }
+ upgrade_lock(Mutex& m_, defer_lock_t)BOOST_NOEXCEPT:
+ m(&m_),is_locked(false)
+ {}
+ upgrade_lock(Mutex& m_, try_to_lock_t) :
+ m(&m_), is_locked(false)
+ {
+ try_lock();
+ }
+
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Clock, class Duration>
+ upgrade_lock(Mutex& mtx, const chrono::time_point<Clock, Duration>& t)
+ : m(&mtx), is_locked(mtx.try_lock_upgrade_until(t))
+ {
+ }
+ template <class Rep, class Period>
+ upgrade_lock(Mutex& mtx, const chrono::duration<Rep, Period>& d)
+ : m(&mtx), is_locked(mtx.try_lock_upgrade_for(d))
+ {
+ }
+#endif
+
+ upgrade_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other) BOOST_NOEXCEPT:
+ m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)
+ {
+ BOOST_THREAD_RV(other).is_locked=false;
+ BOOST_THREAD_RV(other).m=0;
+ }
+
+ BOOST_THREAD_EXPLICIT_LOCK_CONVERSION upgrade_lock(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other):
+ m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)
+ {
+ if(is_locked)
+ {
+ m->unlock_and_lock_upgrade();
+ }
+ BOOST_THREAD_RV(other).is_locked=false;
+ BOOST_THREAD_RV(other).m=0;
+ }
+
+ //std-2104 unique_lock move-assignment should not be noexcept
+ upgrade_lock& operator=(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other) //BOOST_NOEXCEPT
+ {
+ upgrade_lock temp(::boost::move(other));
+ swap(temp);
+ return *this;
+ }
+
+#ifndef BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
+ upgrade_lock& operator=(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other)
+ {
+ upgrade_lock temp(::boost::move(other));
+ swap(temp);
+ return *this;
+ }
+#endif
+
+#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+ // Conversion from shared locking
+ upgrade_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl, try_to_lock_t)
+ : m(0),is_locked(false)
+ {
+ if (BOOST_THREAD_RV(sl).owns_lock())
+ {
+ if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_upgrade())
+ {
+ m = BOOST_THREAD_RV(sl).release();
+ is_locked = true;
+ }
+ }
+ else
+ {
+ m = BOOST_THREAD_RV(sl).release();
+ }
+ }
+
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Clock, class Duration>
+ upgrade_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl,
+ const chrono::time_point<Clock, Duration>& abs_time)
+ : m(0),is_locked(false)
+ {
+ if (BOOST_THREAD_RV(sl).owns_lock())
+ {
+ if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_upgrade_until(abs_time))
+ {
+ m = BOOST_THREAD_RV(sl).release();
+ is_locked = true;
+ }
+ }
+ else
+ {
+ m = BOOST_THREAD_RV(sl).release();
+ }
+ }
+
+ template <class Rep, class Period>
+ upgrade_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl,
+ const chrono::duration<Rep, Period>& rel_time)
+ : m(0),is_locked(false)
+ {
+ if (BOOST_THREAD_RV(sl).owns_lock())
+ {
+ if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_upgrade_for(rel_time))
+ {
+ m = BOOST_THREAD_RV(sl).release();
+ is_locked = true;
+ }
+ }
+ else
+ {
+ m = BOOST_THREAD_RV(sl).release();
+ }
+ }
+#endif // BOOST_THREAD_USES_CHRONO
+#endif // BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+ void swap(upgrade_lock& other)BOOST_NOEXCEPT
+ {
+ std::swap(m,other.m);
+ std::swap(is_locked,other.is_locked);
+ }
+ Mutex* mutex() const BOOST_NOEXCEPT
+ {
+ return m;
+ }
+
+ Mutex* release()BOOST_NOEXCEPT
+ {
+ Mutex* const res=m;
+ m=0;
+ is_locked=false;
+ return res;
+ }
+ ~upgrade_lock()
+ {
+ if (owns_lock())
+ {
+ m->unlock_upgrade();
+ }
+ }
+ void lock()
+ {
+ if (m == 0)
+ {
+ boost::throw_exception(
+ boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
+ }
+ if (owns_lock())
+ {
+ boost::throw_exception(
+ boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost upgrade_lock owns already the mutex"));
+ }
+ m->lock_upgrade();
+ is_locked = true;
+ }
+ bool try_lock()
+ {
+ if (m == 0)
+ {
+ boost::throw_exception(
+ boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
+ }
+ if (owns_lock())
+ {
+ boost::throw_exception(
+ boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost upgrade_lock owns already the mutex"));
+ }
+ is_locked = m->try_lock_upgrade();
+ return is_locked;
+ }
+ void unlock()
+ {
+ if (m == 0)
+ {
+ boost::throw_exception(
+ boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
+ }
+ if (!owns_lock())
+ {
+ boost::throw_exception(
+ boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost upgrade_lock doesn't own the mutex"));
+ }
+ m->unlock_upgrade();
+ is_locked = false;
+ }
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
+ {
+ if(m==0)
+ {
+ boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
+ }
+ if(owns_lock())
+ {
+ boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex"));
+ }
+ is_locked=m->try_lock_upgrade_for(rel_time);
+ return is_locked;
+ }
+ template <class Clock, class Duration>
+ bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
+ {
+ if(m==0)
+ {
+ boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
+ }
+ if(owns_lock())
+ {
+ boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex"));
+ }
+ is_locked=m->try_lock_upgrade_until(abs_time);
+ return is_locked;
+ }
+#endif
+#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
+ typedef void (upgrade_lock::*bool_type)();
+ operator bool_type() const BOOST_NOEXCEPT
+ {
+ return is_locked?&upgrade_lock::lock:0;
+ }
+ bool operator!() const BOOST_NOEXCEPT
+ {
+ return !owns_lock();
+ }
+#else
+ explicit operator bool() const BOOST_NOEXCEPT
+ {
+ return owns_lock();
+ }
+#endif
+ bool owns_lock() const BOOST_NOEXCEPT
+ {
+ return is_locked;
+ }
+ friend class shared_lock<Mutex> ;
+ friend class unique_lock<Mutex> ;
+ };
+
+ template<typename Mutex>
+ void swap(upgrade_lock<Mutex>& lhs, upgrade_lock<Mutex>& rhs)
+ BOOST_NOEXCEPT
+ {
+ lhs.swap(rhs);
+ }
+
+ BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) upgrade_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END
+
+ template<typename Mutex>
+ unique_lock<Mutex>::unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other):
+ m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)
+ {
+ if(is_locked)
+ {
+ m->unlock_upgrade_and_lock();
+ }
+ BOOST_THREAD_RV(other).release();
+ }
+
+ template <class Mutex>
+ class upgrade_to_unique_lock
+ {
+ private:
+ upgrade_lock<Mutex>* source;
+ unique_lock<Mutex> exclusive;
+
+ public:
+ typedef Mutex mutex_type;
+ BOOST_THREAD_MOVABLE_ONLY( upgrade_to_unique_lock)
+
+ explicit upgrade_to_unique_lock(upgrade_lock<Mutex>& m_) :
+ source(&m_), exclusive(::boost::move(*source))
+ {
+ }
+ ~upgrade_to_unique_lock()
+ {
+ if (source)
+ {
+ *source = BOOST_THREAD_MAKE_RV_REF(upgrade_lock<Mutex> (::boost::move(exclusive)));
+ }
+ }
+
+ upgrade_to_unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_to_unique_lock<Mutex> BOOST_THREAD_RV_REF_END other) BOOST_NOEXCEPT:
+ source(BOOST_THREAD_RV(other).source),exclusive(::boost::move(BOOST_THREAD_RV(other).exclusive))
+ {
+ BOOST_THREAD_RV(other).source=0;
+ }
+
+ //std-2104 unique_lock move-assignment should not be noexcept
+ upgrade_to_unique_lock& operator=(BOOST_THREAD_RV_REF_BEG upgrade_to_unique_lock<Mutex> BOOST_THREAD_RV_REF_END other) //BOOST_NOEXCEPT
+ {
+ upgrade_to_unique_lock temp(other);
+ swap(temp);
+ return *this;
+ }
+
+ void swap(upgrade_to_unique_lock& other)BOOST_NOEXCEPT
+ {
+ std::swap(source,other.source);
+ exclusive.swap(other.exclusive);
+ }
+
+#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
+ typedef void (upgrade_to_unique_lock::*bool_type)(upgrade_to_unique_lock&);
+ operator bool_type() const BOOST_NOEXCEPT
+ {
+ return exclusive.owns_lock()?&upgrade_to_unique_lock::swap:0;
+ }
+ bool operator!() const BOOST_NOEXCEPT
+ {
+ return !owns_lock();
+ }
+#else
+ explicit operator bool() const BOOST_NOEXCEPT
+ {
+ return owns_lock();
+ }
+#endif
+
+ bool owns_lock() const BOOST_NOEXCEPT
+ {
+ return exclusive.owns_lock();
+ }
+ Mutex* mutex() const BOOST_NOEXCEPT
+ {
+ return exclusive.mutex();
+ }
+ };
+
+BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) upgrade_to_unique_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END
+
+namespace detail
+{
+ template<typename Mutex>
+ class try_lock_wrapper:
+private unique_lock<Mutex>
+ {
+ typedef unique_lock<Mutex> base;
+ public:
+ BOOST_THREAD_MOVABLE_ONLY(try_lock_wrapper)
+
+ try_lock_wrapper()
+ {}
+
+ explicit try_lock_wrapper(Mutex& m):
+ base(m,try_to_lock)
+ {}
+
+ try_lock_wrapper(Mutex& m_,adopt_lock_t):
+ base(m_,adopt_lock)
+ {
+#if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
+ BOOST_ASSERT(is_locked_by_this_thread(m_));
+#endif
+ }
+ try_lock_wrapper(Mutex& m_,defer_lock_t):
+ base(m_,defer_lock)
+ {}
+ try_lock_wrapper(Mutex& m_,try_to_lock_t):
+ base(m_,try_to_lock)
+ {}
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ try_lock_wrapper(BOOST_THREAD_RV_REF(try_lock_wrapper) other):
+ base(::boost::move(other))
+ {}
+
+#elif defined BOOST_THREAD_USES_MOVE
+ try_lock_wrapper(BOOST_THREAD_RV_REF(try_lock_wrapper) other):
+ base(::boost::move(static_cast<base&>(other)))
+ {}
+
+#else
+ try_lock_wrapper(BOOST_THREAD_RV_REF(try_lock_wrapper) other):
+ base(BOOST_THREAD_RV_REF(base)(*other))
+ {}
+#endif
+ try_lock_wrapper& operator=(BOOST_THREAD_RV_REF_BEG try_lock_wrapper<Mutex> BOOST_THREAD_RV_REF_END other)
+ {
+ try_lock_wrapper temp(other);
+ swap(temp);
+ return *this;
+ }
+ void swap(try_lock_wrapper& other)
+ {
+ base::swap(other);
+ }
+ void lock()
+ {
+ base::lock();
+ }
+ bool try_lock()
+ {
+ return base::try_lock();
+ }
+ void unlock()
+ {
+ base::unlock();
+ }
+ bool owns_lock() const
+ {
+ return base::owns_lock();
+ }
+ Mutex* mutex() const BOOST_NOEXCEPT
+ {
+ return base::mutex();
+ }
+ Mutex* release()
+ {
+ return base::release();
+ }
+
+#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
+ typedef typename base::bool_type bool_type;
+ operator bool_type() const
+ {
+ return base::operator bool_type();
+ }
+ bool operator!() const
+ {
+ return !this->owns_lock();
+ }
+#else
+ explicit operator bool() const
+ {
+ return owns_lock();
+ }
+#endif
+ };
+
+ template<typename Mutex>
+ void swap(try_lock_wrapper<Mutex>& lhs,try_lock_wrapper<Mutex>& rhs)
+ {
+ lhs.swap(rhs);
+ }
+}
+}
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/lockable_adapter.hpp b/src/third_party/boost-1.60.0/boost/thread/lockable_adapter.hpp
new file mode 100644
index 00000000000..93d9ba5023c
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/lockable_adapter.hpp
@@ -0,0 +1,226 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008-2009,2012. Distributed under the 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 http://www.boost.org/libs/thread for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_THREAD_LOCKABLE_ADAPTER_HPP
+#define BOOST_THREAD_LOCKABLE_ADAPTER_HPP
+
+#include <boost/thread/detail/delete.hpp>
+#include <boost/chrono/chrono.hpp>
+
+namespace boost
+{
+
+ //[basic_lockable_adapter
+ template <typename BasicLockable>
+ class basic_lockable_adapter
+ {
+ public:
+ typedef BasicLockable mutex_type;
+
+ protected:
+ mutex_type& lockable() const
+ {
+ return lockable_;
+ }
+ mutable mutex_type lockable_; /*< mutable so that it can be modified by const functions >*/
+ public:
+
+ BOOST_THREAD_NO_COPYABLE( basic_lockable_adapter) /*< no copyable >*/
+
+ basic_lockable_adapter()
+ {}
+
+ void lock() const
+ {
+ lockable().lock();
+ }
+ void unlock() const
+ {
+ lockable().unlock();
+ }
+
+ };
+ //]
+
+ //[lockable_adapter
+ template <typename Lockable>
+ class lockable_adapter : public basic_lockable_adapter<Lockable>
+ {
+ public:
+ typedef Lockable mutex_type;
+
+ bool try_lock() const
+ {
+ return this->lockable().try_lock();
+ }
+ };
+ //]
+
+ //[timed_lockable_adapter
+ template <typename TimedLock>
+ class timed_lockable_adapter: public lockable_adapter<TimedLock>
+ {
+ public:
+ typedef TimedLock mutex_type;
+
+ template <typename Clock, typename Duration>
+ bool try_lock_until(chrono::time_point<Clock, Duration> const & abs_time) const
+ {
+ return this->lockable().try_lock_until(abs_time);
+ }
+ template <typename Rep, typename Period>
+ bool try_lock_for(chrono::duration<Rep, Period> const & rel_time) const
+ {
+ return this->lockable().try_lock_for(rel_time);
+ }
+
+ };
+ //]
+
+ //[shared_lockable_adapter
+ template <typename SharableLock>
+ class shared_lockable_adapter: public timed_lockable_adapter<SharableLock>
+ {
+ public:
+ typedef SharableLock mutex_type;
+
+ void lock_shared() const
+ {
+ this->lockable().lock_shared();
+ }
+ bool try_lock_shared() const
+ {
+ return this->lockable().try_lock_shared();
+ }
+ void unlock_shared() const
+ {
+ this->lockable().unlock_shared();
+ }
+
+ template <typename Clock, typename Duration>
+ bool try_lock_shared_until(chrono::time_point<Clock, Duration> const & abs_time) const
+ {
+ return this->lockable().try_lock_shared_until(abs_time);
+ }
+ template <typename Rep, typename Period>
+ bool try_lock_shared_for(chrono::duration<Rep, Period> const & rel_time) const
+ {
+ return this->lockable().try_lock_shared_for(rel_time);
+ }
+
+ };
+
+ //]
+
+ //[upgrade_lockable_adapter
+ template <typename UpgradableLock>
+ class upgrade_lockable_adapter: public shared_lockable_adapter<UpgradableLock>
+ {
+ public:
+ typedef UpgradableLock mutex_type;
+
+ void lock_upgrade() const
+ {
+ this->lockable().lock_upgrade();
+ }
+
+ bool try_lock_upgrade() const
+ {
+ return this->lockable().try_lock_upgrade();
+ }
+
+ void unlock_upgrade() const
+ {
+ this->lockable().unlock_upgrade();
+ }
+
+ template <typename Clock, typename Duration>
+ bool try_lock_upgrade_until(chrono::time_point<Clock, Duration> const & abs_time) const
+ {
+ return this->lockable().try_lock_upgrade_until(abs_time);
+ }
+ template <typename Rep, typename Period>
+ bool try_lock_upgrade_for(chrono::duration<Rep, Period> const & rel_time) const
+ {
+ return this->lockable().try_lock_upgrade_for(rel_time);
+ }
+
+ bool try_unlock_shared_and_lock() const
+ {
+ return this->lockable().try_unlock_shared_and_lock();
+ }
+
+ template <typename Clock, typename Duration>
+ bool try_unlock_shared_and_lock_until(chrono::time_point<Clock, Duration> const & abs_time) const
+ {
+ return this->lockable().try_unlock_shared_and_lock_until(abs_time);
+ }
+ template <typename Rep, typename Period>
+ bool try_unlock_shared_and_lock_for(chrono::duration<Rep, Period> const & rel_time) const
+ {
+ return this->lockable().try_unlock_shared_and_lock_for(rel_time);
+ }
+
+ void unlock_and_lock_shared() const
+ {
+ this->lockable().unlock_and_lock_shared();
+ }
+
+ bool try_unlock_shared_and_lock_upgrade() const
+ {
+ return this->lockable().try_unlock_shared_and_lock_upgrade();
+ }
+
+ template <typename Clock, typename Duration>
+ bool try_unlock_shared_and_lock_upgrade_until(chrono::time_point<Clock, Duration> const & abs_time) const
+ {
+ return this->lockable().try_unlock_shared_and_lock_upgrade_until(abs_time);
+ }
+ template <typename Rep, typename Period>
+ bool try_unlock_shared_and_lock_upgrade_for(chrono::duration<Rep, Period> const & rel_time) const
+ {
+ return this->lockable().try_unlock_shared_and_lock_upgrade_for(rel_time);
+ }
+
+ void unlock_and_lock_upgrade() const
+ {
+ this->lockable().unlock_and_lock_upgrade();
+ }
+
+ void unlock_upgrade_and_lock() const
+ {
+ this->lockable().unlock_upgrade_and_lock();
+ }
+
+ bool try_unlock_upgrade_and_lock() const
+ {
+ return this->lockable().try_unlock_upgrade_and_lock();
+ }
+ template <typename Clock, typename Duration>
+ bool try_unlock_upgrade_and_lock_until(chrono::time_point<Clock, Duration> const & abs_time) const
+ {
+ return this->lockable().try_unlock_upgrade_and_lock_until(abs_time);
+ }
+ template <typename Rep, typename Period>
+ bool try_unlock_upgrade_and_lock_for(chrono::duration<Rep, Period> const & rel_time) const
+ {
+ return this->lockable().try_unlock_upgrade_and_lock_for(rel_time);
+ }
+
+ void unlock_upgrade_and_lock_shared() const
+ {
+ this->lockable().unlock_upgrade_and_lock_shared();
+ }
+
+ };
+//]
+
+}
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/lockable_concepts.hpp b/src/third_party/boost-1.60.0/boost/thread/lockable_concepts.hpp
new file mode 100644
index 00000000000..bedd962e3be
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/lockable_concepts.hpp
@@ -0,0 +1,157 @@
+// (C) Copyright 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)
+
+#ifndef BOOST_THREAD_LOCKABLE_CONCEPTS_HPP
+#define BOOST_THREAD_LOCKABLE_CONCEPTS_HPP
+
+#include <boost/chrono/chrono.hpp>
+#include <boost/concept_check.hpp>
+
+namespace boost
+{
+
+ /**
+ * BasicLockable object supports the basic features
+ * required to delimit a critical region
+ * Supports the basic lock and unlock functions.
+ */
+
+ //[BasicLockable
+ template <typename Mutex>
+ struct BasicLockable
+ {
+
+ BOOST_CONCEPT_USAGE(BasicLockable)
+ {
+ l.lock();
+ l.unlock();
+ }
+ BasicLockable() : l(*static_cast<Mutex*>(0)) {}
+ private:
+ BasicLockable operator=(BasicLockable const&);
+
+ Mutex& l;
+ }
+ ;
+ //]
+ /**
+ * Lockable extends BasicLockable
+ * with try_lock functions.
+ */
+
+ //[Lockable
+ template <typename Mutex>
+ struct Lockable
+ {
+ BOOST_CONCEPT_ASSERT(( BasicLockable<Mutex> ));
+
+ BOOST_CONCEPT_USAGE(Lockable)
+ {
+ if (l.try_lock()) return;
+ }
+ Lockable() : l(*static_cast<Mutex*>(0)) {}
+ private:
+ Lockable operator=(Lockable const&);
+ Mutex& l;
+ };
+ //]
+
+ /**
+ * TimedLockable object extends Lockable
+ * with timed lock functions: try_lock_until and try_lock_for and the exception based lock_until and lock_for
+ */
+
+ //[TimedLockable
+ template <typename Mutex>
+ struct TimedLockable
+ {
+ BOOST_CONCEPT_ASSERT(( Lockable<Mutex> ));
+
+ BOOST_CONCEPT_USAGE(TimedLockable)
+ {
+ if (l.try_lock_until(t)) return;
+ if (l.try_lock_for(d)) return;
+ }
+ TimedLockable() : l(*static_cast<Mutex*>(0)) {}
+ private:
+ TimedLockable operator=(TimedLockable const&);
+ Mutex& l;
+ chrono::system_clock::time_point t;
+ chrono::system_clock::duration d;
+ };
+ //]
+
+ /**
+ * SharedLockable object extends TimedLockable
+ * with the lock_shared, lock_shared_until, lock_shared_for, try_lock_shared_until, try_lock_shared
+ * and unlock_shared functions
+ */
+ //[SharedLockable
+ template <typename Mutex>
+ struct SharedLockable
+ {
+ BOOST_CONCEPT_ASSERT(( TimedLockable<Mutex> ));
+
+ BOOST_CONCEPT_USAGE(SharedLockable)
+ {
+ l.lock_shared();
+ l.unlock_shared();
+ if (l.try_lock_shared()) return;
+ if (l.try_lock_shared_until(t)) return;
+ if (l.try_lock_shared_for(d)) return;
+ }
+ SharedLockable() : l(*static_cast<Mutex*>(0)) {}
+ private:
+ SharedLockable operator=(SharedLockable const&);
+ Mutex& l;
+ chrono::system_clock::time_point t;
+ chrono::system_clock::duration d;
+ };
+ //]
+
+ /**
+ * UpgradeLockable object extends SharedLockable
+ * with the lock_upgrade, lock_upgrade_until, unlock_upgrade_and_lock,
+ * unlock_and_lock_shared and unlock_upgrade_and_lock_shared functions
+ */
+
+ //[UpgradeLockable
+ template <typename Mutex>
+ struct UpgradeLockable
+ {
+ BOOST_CONCEPT_ASSERT(( SharedLockable<Mutex> ));
+
+ BOOST_CONCEPT_USAGE(UpgradeLockable)
+ {
+ l.lock_upgrade();
+ l.unlock_upgrade();
+ if (l.try_lock_upgrade()) return;
+ if (l.try_lock_upgrade_until(t)) return;
+ if (l.try_lock_upgrade_for(d)) return;
+ if (l.try_unlock_shared_and_lock()) return;
+ if (l.try_unlock_shared_and_lock_until(t)) return;
+ if (l.try_unlock_shared_and_lock_for(d)) return;
+ l.unlock_and_lock_shared();
+ if (l.try_unlock_shared_and_lock_upgrade()) return;
+ if (l.try_unlock_shared_and_lock_upgrade_until(t)) return;
+ if (l.try_unlock_shared_and_lock_upgrade_for(d)) return;
+ l.unlock_and_lock_upgrade();
+ l.unlock_upgrade_and_lock();
+ if (l.try_unlock_upgrade_and_lock()) return;
+ if (l.try_unlock_upgrade_and_lock_until(t)) return;
+ if (l.try_unlock_upgrade_and_lock_for(d)) return;
+ l.unlock_upgrade_and_lock_shared();
+ }
+ UpgradeLockable() : l(*static_cast<Mutex*>(0)) {}
+ private:
+ UpgradeLockable operator=(UpgradeLockable const&);
+ Mutex& l;
+ chrono::system_clock::time_point t;
+ chrono::system_clock::duration d;
+ };
+ //]
+
+}
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/lockable_traits.hpp b/src/third_party/boost-1.60.0/boost/thread/lockable_traits.hpp
new file mode 100644
index 00000000000..8a17ae72d3f
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/lockable_traits.hpp
@@ -0,0 +1,207 @@
+// Distributed under the 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 2007 Anthony Williams
+// (C) Copyright 2011-2012 Vicente J. Botet Escriba
+
+#ifndef BOOST_THREAD_LOCKABLE_TRAITS_HPP
+#define BOOST_THREAD_LOCKABLE_TRAITS_HPP
+
+#include <boost/thread/detail/config.hpp>
+
+#include <boost/assert.hpp>
+#include <boost/detail/workaround.hpp>
+#include <boost/type_traits/is_class.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+// todo make use of integral_constant, true_type and false_type
+
+namespace boost
+{
+ namespace sync
+ {
+
+#if defined(BOOST_NO_SFINAE) || \
+ BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) || \
+ BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
+#if ! defined BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
+#define BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
+#endif
+#endif
+
+#ifndef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
+ namespace detail
+ {
+#define BOOST_THREAD_DEFINE_HAS_MEMBER_CALLED(member_name) \
+ template<typename T, bool=boost::is_class<T>::value> \
+ struct has_member_called_##member_name \
+ { \
+ BOOST_STATIC_CONSTANT(bool, value=false); \
+ }; \
+ \
+ template<typename T> \
+ struct has_member_called_##member_name<T,true> \
+ { \
+ typedef char true_type; \
+ struct false_type \
+ { \
+ true_type dummy[2]; \
+ }; \
+ \
+ struct fallback { int member_name; }; \
+ struct derived: \
+ T, fallback \
+ { \
+ derived(); \
+ }; \
+ \
+ template<int fallback::*> struct tester; \
+ \
+ template<typename U> \
+ static false_type has_member(tester<&U::member_name>*); \
+ template<typename U> \
+ static true_type has_member(...); \
+ \
+ BOOST_STATIC_CONSTANT( \
+ bool, value=sizeof(has_member<derived>(0))==sizeof(true_type)); \
+ }
+
+ BOOST_THREAD_DEFINE_HAS_MEMBER_CALLED(lock)
+; BOOST_THREAD_DEFINE_HAS_MEMBER_CALLED(unlock);
+ BOOST_THREAD_DEFINE_HAS_MEMBER_CALLED(try_lock);
+
+ template<typename T,bool=has_member_called_lock<T>::value >
+ struct has_member_lock
+ {
+ BOOST_STATIC_CONSTANT(bool, value=false);
+ };
+
+ template<typename T>
+ struct has_member_lock<T,true>
+ {
+ typedef char true_type;
+ struct false_type
+ {
+ true_type dummy[2];
+ };
+
+ template<typename U,typename V>
+ static true_type has_member(V (U::*)());
+ template<typename U>
+ static false_type has_member(U);
+
+ BOOST_STATIC_CONSTANT(
+ bool,value=sizeof(has_member_lock<T>::has_member(&T::lock))==sizeof(true_type));
+ };
+
+ template<typename T,bool=has_member_called_unlock<T>::value >
+ struct has_member_unlock
+ {
+ BOOST_STATIC_CONSTANT(bool, value=false);
+ };
+
+ template<typename T>
+ struct has_member_unlock<T,true>
+ {
+ typedef char true_type;
+ struct false_type
+ {
+ true_type dummy[2];
+ };
+
+ template<typename U,typename V>
+ static true_type has_member(V (U::*)());
+ template<typename U>
+ static false_type has_member(U);
+
+ BOOST_STATIC_CONSTANT(
+ bool,value=sizeof(has_member_unlock<T>::has_member(&T::unlock))==sizeof(true_type));
+ };
+
+ template<typename T,bool=has_member_called_try_lock<T>::value >
+ struct has_member_try_lock
+ {
+ BOOST_STATIC_CONSTANT(bool, value=false);
+ };
+
+ template<typename T>
+ struct has_member_try_lock<T,true>
+ {
+ typedef char true_type;
+ struct false_type
+ {
+ true_type dummy[2];
+ };
+
+ template<typename U>
+ static true_type has_member(bool (U::*)());
+ template<typename U>
+ static false_type has_member(U);
+
+ BOOST_STATIC_CONSTANT(
+ bool,value=sizeof(has_member_try_lock<T>::has_member(&T::try_lock))==sizeof(true_type));
+ };
+
+ }
+
+ template<typename T>
+ struct is_basic_lockable
+ {
+ BOOST_STATIC_CONSTANT(bool, value = detail::has_member_lock<T>::value &&
+ detail::has_member_unlock<T>::value);
+ };
+ template<typename T>
+ struct is_lockable
+ {
+ BOOST_STATIC_CONSTANT(bool, value =
+ is_basic_lockable<T>::value &&
+ detail::has_member_try_lock<T>::value);
+ };
+
+#else
+ template<typename T>
+ struct is_basic_lockable
+ {
+ BOOST_STATIC_CONSTANT(bool, value = false);
+ };
+ template<typename T>
+ struct is_lockable
+ {
+ BOOST_STATIC_CONSTANT(bool, value = false);
+ };
+#endif
+
+ template<typename T>
+ struct is_recursive_mutex_sur_parole
+ {
+ BOOST_STATIC_CONSTANT(bool, value = false);
+ };
+ template<typename T>
+ struct is_recursive_mutex_sur_parolle : is_recursive_mutex_sur_parole<T>
+ {
+ };
+
+ template<typename T>
+ struct is_recursive_basic_lockable
+ {
+ BOOST_STATIC_CONSTANT(bool, value = is_basic_lockable<T>::value &&
+ is_recursive_mutex_sur_parolle<T>::value);
+ };
+ template<typename T>
+ struct is_recursive_lockable
+ {
+ BOOST_STATIC_CONSTANT(bool, value = is_lockable<T>::value &&
+ is_recursive_mutex_sur_parolle<T>::value);
+ };
+ }
+ template<typename T>
+ struct is_mutex_type
+ {
+ BOOST_STATIC_CONSTANT(bool, value = sync::is_lockable<T>::value);
+ };
+
+}
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/locks.hpp b/src/third_party/boost-1.60.0/boost/thread/locks.hpp
new file mode 100644
index 00000000000..6749964cf52
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/locks.hpp
@@ -0,0 +1,16 @@
+// Distributed under the 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 2007 Anthony Williams
+// (C) Copyright 2011-2012 Vicente J. Botet Escriba
+
+#ifndef BOOST_THREAD_LOCKS_HPP
+#define BOOST_THREAD_LOCKS_HPP
+
+#include <boost/thread/lock_algorithms.hpp>
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/lock_guard.hpp>
+#include <boost/thread/lockable_traits.hpp>
+#include <boost/thread/lock_options.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/mutex.hpp b/src/third_party/boost-1.60.0/boost/thread/mutex.hpp
new file mode 100644
index 00000000000..05c60941c46
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/mutex.hpp
@@ -0,0 +1,53 @@
+#ifndef BOOST_THREAD_MUTEX_HPP
+#define BOOST_THREAD_MUTEX_HPP
+
+// mutex.hpp
+//
+// (C) Copyright 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/detail/platform.hpp>
+#if defined(BOOST_THREAD_PLATFORM_WIN32)
+#include <boost/thread/win32/mutex.hpp>
+#elif defined(BOOST_THREAD_PLATFORM_PTHREAD)
+#include <boost/thread/pthread/mutex.hpp>
+#else
+#error "Boost threads unavailable on this platform"
+#endif
+
+#include <boost/thread/lockable_traits.hpp>
+
+
+namespace boost
+{
+ namespace sync
+ {
+#ifdef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
+ template<>
+ struct is_basic_lockable<mutex>
+ {
+ BOOST_STATIC_CONSTANT(bool, value = true);
+ };
+ template<>
+ struct is_lockable<mutex>
+ {
+ BOOST_STATIC_CONSTANT(bool, value = true);
+ };
+ template<>
+ struct is_basic_lockable<timed_mutex>
+ {
+ BOOST_STATIC_CONSTANT(bool, value = true);
+ };
+ template<>
+ struct is_lockable<timed_mutex>
+ {
+ BOOST_STATIC_CONSTANT(bool, value = true);
+ };
+#endif
+ }
+}
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/null_mutex.hpp b/src/third_party/boost-1.60.0/boost/thread/null_mutex.hpp
new file mode 100644
index 00000000000..f439f9ffb27
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/null_mutex.hpp
@@ -0,0 +1,243 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008-2009,2012. Distributed under the 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 http://www.boost.org/libs/thread for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_THREAD_NULL_MUTEX_HPP
+#define BOOST_THREAD_NULL_MUTEX_HPP
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/detail/delete.hpp>
+#include <boost/chrono/chrono.hpp>
+
+/// \file
+/// Describes null_mutex class
+
+namespace boost
+{
+
+ /// Implements a mutex that simulates a mutex without doing any operation and
+ /// simulates a successful operation.
+ class null_mutex
+ {
+ public:
+
+ BOOST_THREAD_NO_COPYABLE( null_mutex) /*< no copyable >*/
+
+ null_mutex() {}
+
+ /// Simulates a mutex lock() operation. Empty function.
+ void lock()
+ {
+ }
+
+ /// Simulates a mutex try_lock() operation.
+ /// Equivalent to "return true;"
+ bool try_lock()
+ {
+ return true;
+ }
+
+ /// Simulates a mutex unlock() operation.
+ /// Empty function.
+ void unlock()
+ {
+ }
+
+#ifdef BOOST_THREAD_USES_CHRONO
+ /// Simulates a mutex try_lock_until() operation.
+ /// Equivalent to "return true;"
+ template <typename Clock, typename Duration>
+ bool try_lock_until(chrono::time_point<Clock, Duration> const &)
+ {
+ return true;
+ }
+
+ /// Simulates a mutex try_lock_for() operation.
+ /// Equivalent to "return true;"
+ template <typename Rep, typename Period>
+ bool try_lock_for(chrono::duration<Rep, Period> const &)
+ {
+ return true;
+ }
+#endif
+
+ /// Simulates a mutex lock_shared() operation.
+ /// Empty function.
+ void lock_shared()
+ {
+ }
+
+ /// Simulates a mutex try_lock_shared() operation.
+ /// Equivalent to "return true;"
+ bool try_lock_shared()
+ {
+ return true;
+ }
+
+ /// Simulates a mutex unlock_shared() operation.
+ /// Empty function.
+ void unlock_shared()
+ {
+ }
+
+ /// Simulates a mutex try_lock_shared_until() operation.
+ /// Equivalent to "return true;"
+ template <typename Clock, typename Duration>
+ bool try_lock_shared_until(chrono::time_point<Clock, Duration> const &)
+ {
+ return true;
+ }
+ /// Simulates a mutex try_lock_shared_for() operation.
+ /// Equivalent to "return true;"
+ template <typename Rep, typename Period>
+ bool try_lock_shared_for(chrono::duration<Rep, Period> const &)
+ {
+ return true;
+ }
+
+ /// Simulates a mutex lock_upgrade() operation.
+ /// Empty function.
+ void lock_upgrade()
+ {
+ }
+
+ /// Simulates a mutex try_lock_upgrade() operation.
+ /// Equivalent to "return true;"
+ bool try_lock_upgrade()
+ {
+ return true;
+ }
+
+ /// Simulates a mutex unlock_upgrade() operation.
+ /// Empty function.
+ void unlock_upgrade()
+ {
+ }
+
+ /// Simulates a mutex try_lock_upgrade_until() operation.
+ /// Equivalent to "return true;"
+ template <typename Clock, typename Duration>
+ bool try_lock_upgrade_until(chrono::time_point<Clock, Duration> const &)
+ {
+ return true;
+ }
+
+ /// Simulates a mutex try_lock_upgrade_for() operation.
+ /// Equivalent to "return true;"
+ template <typename Rep, typename Period>
+ bool try_lock_upgrade_for(chrono::duration<Rep, Period> const &)
+ {
+ return true;
+ }
+
+ /// Simulates a mutex try_unlock_shared_and_lock() operation.
+ /// Equivalent to "return true;"
+ bool try_unlock_shared_and_lock()
+ {
+ return true;
+ }
+
+#ifdef BOOST_THREAD_USES_CHRONO
+ /// Simulates a mutex try_unlock_shared_and_lock_until() operation.
+ /// Equivalent to "return true;"
+ template <typename Clock, typename Duration>
+ bool try_unlock_shared_and_lock_until(chrono::time_point<Clock, Duration> const &)
+ {
+ return true;
+ }
+
+ /// Simulates a mutex try_unlock_shared_and_lock_for() operation.
+ /// Equivalent to "return true;"
+ template <typename Rep, typename Period>
+ bool try_unlock_shared_and_lock_for(chrono::duration<Rep, Period> const &)
+ {
+ return true;
+ }
+#endif
+
+ /// Simulates unlock_and_lock_shared().
+ /// Empty function.
+ void unlock_and_lock_shared()
+ {
+ }
+
+ /// Simulates a mutex try_unlock_shared_and_lock_upgrade() operation.
+ /// Equivalent to "return true;"
+ bool try_unlock_shared_and_lock_upgrade()
+ {
+ return true;
+ }
+
+#ifdef BOOST_THREAD_USES_CHRONO
+ /// Simulates a mutex try_unlock_shared_and_lock_upgrade_until() operation.
+ /// Equivalent to "return true;"
+ template <typename Clock, typename Duration>
+ bool try_unlock_shared_and_lock_upgrade_until(chrono::time_point<Clock, Duration> const &)
+ {
+ return true;
+ }
+
+ /// Simulates a mutex try_unlock_shared_and_lock_upgrade_for() operation.
+ /// Equivalent to "return true;"
+ template <typename Rep, typename Period>
+ bool try_unlock_shared_and_lock_upgrade_for(chrono::duration<Rep, Period> const &)
+ {
+ return true;
+ }
+#endif
+
+ /// Simulates unlock_and_lock_upgrade().
+ /// Empty function.
+ void unlock_and_lock_upgrade()
+ {
+ }
+
+ /// Simulates unlock_upgrade_and_lock().
+ /// Empty function.
+ void unlock_upgrade_and_lock()
+ {
+ }
+
+ /// Simulates a mutex try_unlock_upgrade_and_lock() operation.
+ /// Equivalent to "return true;"
+ bool try_unlock_upgrade_and_lock()
+ {
+ return true;
+ }
+
+#ifdef BOOST_THREAD_USES_CHRONO
+ /// Simulates a mutex try_unlock_upgrade_and_lock_until() operation.
+ /// Equivalent to "return true;"
+ template <typename Clock, typename Duration>
+ bool try_unlock_upgrade_and_lock_until(chrono::time_point<Clock, Duration> const &)
+ {
+ return true;
+ }
+
+ /// Simulates a mutex try_unlock_upgrade_and_lock_for() operation.
+ /// Equivalent to "return true;"
+ template <typename Rep, typename Period>
+ bool try_unlock_upgrade_and_lock_for(chrono::duration<Rep, Period> const &)
+ {
+ return true;
+ }
+#endif
+
+ /// Simulates unlock_upgrade_and_lock_shared().
+ /// Empty function.
+ void unlock_upgrade_and_lock_shared()
+ {
+ }
+
+ };
+
+} //namespace boost {
+
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/once.hpp b/src/third_party/boost-1.60.0/boost/thread/once.hpp
new file mode 100644
index 00000000000..9fcfb533397
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/once.hpp
@@ -0,0 +1,44 @@
+#ifndef BOOST_THREAD_ONCE_HPP
+#define BOOST_THREAD_ONCE_HPP
+
+// once.hpp
+//
+// (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)
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/detail/platform.hpp>
+#if defined(BOOST_THREAD_PLATFORM_WIN32)
+#include <boost/thread/win32/once.hpp>
+#elif defined(BOOST_THREAD_PLATFORM_PTHREAD)
+#if defined BOOST_THREAD_ONCE_FAST_EPOCH
+#include <boost/thread/pthread/once.hpp>
+#elif defined BOOST_THREAD_ONCE_ATOMIC
+#include <boost/thread/pthread/once_atomic.hpp>
+#else
+#error "Once Not Implemented"
+#endif
+#else
+#error "Boost threads unavailable on this platform"
+#endif
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ // template<class Callable, class ...Args> void
+ // call_once(once_flag& flag, Callable&& func, Args&&... args);
+template<typename Function>
+inline void call_once(Function func,once_flag& flag)
+//inline void call_once(void (*func)(),once_flag& flag)
+ {
+ call_once(flag,func);
+ }
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/ostream_buffer.hpp b/src/third_party/boost-1.60.0/boost/thread/ostream_buffer.hpp
new file mode 100644
index 00000000000..cc02a9c0cee
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/ostream_buffer.hpp
@@ -0,0 +1,45 @@
+// (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)
+
+
+#ifndef BOOST_THREAD_OSTREAM_BUFFER_HPP
+#define BOOST_THREAD_OSTREAM_BUFFER_HPP
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/detail/delete.hpp>
+#include <sstream>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+
+ template <typename OStream>
+ class ostream_buffer
+ {
+ public:
+ typedef std::basic_ostringstream<typename OStream::char_type, typename OStream::traits_type> stream_type;
+ ostream_buffer(OStream& os) :
+ os_(os)
+ {
+ }
+ ~ostream_buffer()
+ {
+ os_ << o_str_.str();
+ }
+ stream_type& stream()
+ {
+ return o_str_;
+ }
+ private:
+ OStream& os_;
+ stream_type o_str_;
+ };
+
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/poly_lockable.hpp b/src/third_party/boost-1.60.0/boost/thread/poly_lockable.hpp
new file mode 100644
index 00000000000..fffcbce1330
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/poly_lockable.hpp
@@ -0,0 +1,68 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008-2009,2012. Distributed under the 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 http://www.boost.org/libs/thread for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_THREAD_POLY_LOCKABLE_HPP
+#define BOOST_THREAD_POLY_LOCKABLE_HPP
+
+#include <boost/thread/detail/delete.hpp>
+#include <boost/chrono/chrono.hpp>
+
+namespace boost
+{
+
+ //[basic_poly_lockable
+ class basic_poly_lockable
+ {
+ public:
+
+ virtual ~basic_poly_lockable() = 0;
+
+ virtual void lock() = 0;
+ virtual void unlock() = 0;
+
+ };
+ //]
+
+ //[poly_lockable
+ class poly_lockable : public basic_poly_lockable
+ {
+ public:
+
+ virtual ~poly_lockable() = 0;
+ virtual bool try_lock() = 0;
+ };
+ //]
+
+ //[timed_poly_lockable
+ class timed_poly_lockable: public poly_lockable
+ {
+ public:
+ virtual ~timed_poly_lockable()=0;
+
+ virtual bool try_lock_until(chrono::system_clock::time_point const & abs_time)=0;
+ virtual bool try_lock_until(chrono::steady_clock::time_point const & abs_time)=0;
+ template <typename Clock, typename Duration>
+ bool try_lock_until(chrono::time_point<Clock, Duration> const & abs_time)
+ {
+ return try_lock_until(time_point_cast<Clock::time_point>(abs_time));
+ }
+
+ virtual bool try_lock_for(chrono::nanoseconds const & relative_time)=0;
+ template <typename Rep, typename Period>
+ bool try_lock_for(chrono::duration<Rep, Period> const & rel_time)
+ {
+ return try_lock_for(duration_cast<Clock::duration>(rel_time));
+ }
+
+ };
+ //]
+
+}
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/poly_lockable_adapter.hpp b/src/third_party/boost-1.60.0/boost/thread/poly_lockable_adapter.hpp
new file mode 100644
index 00000000000..448789ecbc8
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/poly_lockable_adapter.hpp
@@ -0,0 +1,89 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008-2009,2012. Distributed under the 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 http://www.boost.org/libs/thread for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_THREAD_POLY_LOCKABLE_ADAPTER_HPP
+#define BOOST_THREAD_POLY_LOCKABLE_ADAPTER_HPP
+
+#include <boost/thread/poly_lockable.hpp>
+
+namespace boost
+{
+
+ //[poly_basic_lockable_adapter
+ template <typename Mutex, typename Base=poly_basic_lockable>
+ class poly_basic_lockable_adapter : public Base
+ {
+ public:
+ typedef Mutex mutex_type;
+
+ protected:
+ mutex_type& mtx() const
+ {
+ return mtx_;
+ }
+ mutable mutex_type mtx_; /*< mutable so that it can be modified by const functions >*/
+ public:
+
+ BOOST_THREAD_NO_COPYABLE( poly_basic_lockable_adapter) /*< no copyable >*/
+
+ poly_basic_lockable_adapter()
+ {}
+
+ void lock()
+ {
+ mtx().lock();
+ }
+ void unlock()
+ {
+ mtx().unlock();
+ }
+
+ };
+ //]
+
+ //[poly_lockable_adapter
+ template <typename Mutex, typename Base=poly_lockable>
+ class poly_lockable_adapter : public poly_basic_lockable_adapter<Mutex, Base>
+ {
+ public:
+ typedef Mutex mutex_type;
+
+ bool try_lock()
+ {
+ return this->mtx().try_lock();
+ }
+ };
+ //]
+
+ //[poly_timed_lockable_adapter
+ template <typename Mutex, typename Base=poly_timed_lockable>
+ class poly_timed_lockable_adapter: public poly_lockable_adapter<Mutex, Base>
+ {
+ public:
+ typedef Mutex mutex_type;
+
+ bool try_lock_until(chrono::system_clock::time_point const & abs_time)
+ {
+ return this->mtx().try_lock_until(abs_time);
+ }
+ bool try_lock_until(chrono::steady_clock::time_point const & abs_time)
+ {
+ return this->mtx().try_lock_until(abs_time);
+ }
+ bool try_lock_for(chrono::nanoseconds const & rel_time)
+ {
+ return this->mtx().try_lock_for(rel_time);
+ }
+
+ };
+ //]
+
+}
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/poly_shared_lockable.hpp b/src/third_party/boost-1.60.0/boost/thread/poly_shared_lockable.hpp
new file mode 100644
index 00000000000..4348ed76c25
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/poly_shared_lockable.hpp
@@ -0,0 +1,135 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008-2009,2012. Distributed under the 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 http://www.boost.org/libs/thread for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_THREAD_POLY_SHARED_LOCKABLE_HPP
+#define BOOST_THREAD_POLY_SHARED_LOCKABLE_HPP
+
+#include <boost/thread/poly_lockable.hpp>
+#include <boost/chrono/chrono.hpp>
+
+namespace boost
+{
+
+
+ //[shared_poly_lockable
+ class shared_poly_lockable: public timed_poly_lockable
+ {
+ public:
+ virtual ~shared_poly_lockable() = 0;
+
+ virtual void lock_shared() = 0;
+ virtual bool try_lock_shared() = 0;
+ virtual void unlock_shared() = 0;
+
+ virtual bool try_lock_shared_until(chrono::system_clock::time_point const & abs_time)=0;
+ virtual bool try_lock_shared_until(chrono::steady_clock::time_point const & abs_time)=0;
+ template <typename Clock, typename Duration>
+ bool try_lock_shared_until(chrono::time_point<Clock, Duration> const & abs_time)
+ {
+ return try_lock_shared_until(time_point_cast<Clock::time_point>(abs_time));
+ }
+
+ virtual bool try_lock_shared_for(chrono::nanoseconds const & relative_time)=0;
+ template <typename Rep, typename Period>
+ bool try_lock_shared_for(chrono::duration<Rep, Period> const & rel_time)
+ {
+ return try_lock_shared_for(duration_cast<Clock::duration>(rel_time));
+ }
+
+ };
+
+ //]
+
+ //[upgrade_poly_lockable
+ class upgrade_poly_lockable: public shared_poly_lockable
+ {
+ public:
+ virtual ~upgrade_poly_lockable() = 0;
+
+ virtual void lock_upgrade() = 0;
+ virtual bool try_lock_upgrade() = 0;
+ virtual void unlock_upgrade() = 0;
+
+ virtual bool try_lock_upgrade_until(chrono::system_clock::time_point const & abs_time)=0;
+ virtual bool try_lock_upgrade_until(chrono::steady_clock::time_point const & abs_time)=0;
+ template <typename Clock, typename Duration>
+ bool try_lock_upgrade_until(chrono::time_point<Clock, Duration> const & abs_time)
+ {
+ return try_lock_upgrade_until(time_point_cast<Clock::time_point>(abs_time));
+ }
+
+ virtual bool try_lock_upgrade_for(chrono::nanoseconds const & relative_time)=0;
+ template <typename Rep, typename Period>
+ bool try_lock_upgrade_for(chrono::duration<Rep, Period> const & rel_time)
+ {
+ return try_lock_upgrade_for(duration_cast<Clock::duration>(rel_time));
+ }
+
+ virtual bool try_unlock_shared_and_lock() = 0;
+
+ virtual bool try_unlock_shared_and_lock_until(chrono::system_clock::time_point const & abs_time)=0;
+ virtual bool try_unlock_shared_and_lock_until(chrono::steady_clock::time_point const & abs_time)=0;
+ template <typename Clock, typename Duration>
+ bool try_unlock_shared_and_lock_until(chrono::time_point<Clock, Duration> const & abs_time)
+ {
+ return try_unlock_shared_and_lock_until(time_point_cast<Clock::time_point>(abs_time));
+ }
+
+ virtual bool try_unlock_shared_and_lock_for(chrono::nanoseconds const & relative_time)=0;
+ template <typename Rep, typename Period>
+ bool try_unlock_shared_and_lock_for(chrono::duration<Rep, Period> const & rel_time)
+ {
+ return try_unlock_shared_and_lock_for(duration_cast<Clock::duration>(rel_time));
+ }
+
+ virtual void unlock_and_lock_shared() = 0;
+ virtual bool try_unlock_shared_and_lock_upgrade() = 0;
+
+ virtual bool try_unlock_shared_and_lock_upgrade_until(chrono::system_clock::time_point const & abs_time)=0;
+ virtual bool try_unlock_shared_and_lock_upgrade_until(chrono::steady_clock::time_point const & abs_time)=0;
+ template <typename Clock, typename Duration>
+ bool try_unlock_shared_and_lock_upgrade_until(chrono::time_point<Clock, Duration> const & abs_time)
+ {
+ return try_unlock_shared_and_lock_upgrade_until(time_point_cast<Clock::time_point>(abs_time));
+ }
+
+ virtual bool try_unlock_shared_and_lock_upgrade_for(chrono::nanoseconds const & relative_time)=0;
+ template <typename Rep, typename Period>
+ bool try_unlock_shared_and_lock_upgrade_for(chrono::duration<Rep, Period> const & rel_time)
+ {
+ return try_unlock_shared_and_lock_upgrade_for(duration_cast<Clock::duration>(rel_time));
+ }
+
+ virtual void unlock_and_lock_upgrade() = 0;
+ virtual void unlock_upgrade_and_lock() = 0;
+ virtual bool try_unlock_upgrade_and_lock() = 0;
+
+ virtual bool try_unlock_upgrade_and_lock_until(chrono::system_clock::time_point const & abs_time)=0;
+ virtual bool try_unlock_upgrade_and_lock_until(chrono::steady_clock::time_point const & abs_time)=0;
+ template <typename Clock, typename Duration>
+ bool try_unlock_upgrade_and_lock_until(chrono::time_point<Clock, Duration> const & abs_time)
+ {
+ return try_unlock_upgrade_and_lock_until(time_point_cast<Clock::time_point>(abs_time));
+ }
+
+ virtual bool try_unlock_upgrade_and_lock_for(chrono::nanoseconds const & relative_time)=0;
+ template <typename Rep, typename Period>
+ bool try_unlock_upgrade_and_lock_for(chrono::duration<Rep, Period> const & rel_time)
+ {
+ return try_unlock_upgrade_and_lock_for(duration_cast<Clock::duration>(rel_time));
+ }
+
+ virtual void unlock_upgrade_and_lock_shared() = 0;
+
+ };
+//]
+
+}
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/poly_shared_lockable_adapter.hpp b/src/third_party/boost-1.60.0/boost/thread/poly_shared_lockable_adapter.hpp
new file mode 100644
index 00000000000..f1361289078
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/poly_shared_lockable_adapter.hpp
@@ -0,0 +1,170 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008-2009,2012. Distributed under the 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 http://www.boost.org/libs/thread for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_THREAD_POLY_SHARED_LOCKABLE_ADAPTER_HPP
+#define BOOST_THREAD_POLY_SHARED_LOCKABLE_ADAPTER_HPP
+
+#include <boost/thread/poly_lockable_adapter.hpp>
+#include <boost/thread/poly_shared_lockable.hpp>
+
+namespace boost
+{
+
+ //[shared_lockable_adapter
+ template <typename Mutex, typename Base=poly_shared_lockable>
+ class poly_shared_lockable_adapter: public poly_timed_lockable_adapter<Mutex, Base>
+ {
+ public:
+ typedef Mutex mutex_type;
+
+ void lock_shared()
+ {
+ this->mtx().lock_shared();
+ }
+ bool try_lock_shared()
+ {
+ return this->mtx().try_lock_shared();
+ }
+ void unlock_shared()
+ {
+ this->mtx().unlock_shared();
+ }
+
+ bool try_lock_shared_until(chrono::system_clock::time_point const & abs_time)
+ {
+ return this->mtx().try_lock_shared_until(abs_time);
+ }
+ bool try_lock_shared_until(chrono::steady_clock::time_point const & abs_time)
+ {
+ return this->mtx().try_lock_shared_until(abs_time);
+ }
+ bool try_lock_shared_for(chrono::nanoseconds const & rel_time)
+ {
+ return this->mtx().try_lock_shared_for(rel_time);
+ }
+
+ };
+
+ //]
+
+ //[upgrade_lockable_adapter
+ template <typename Mutex, typename Base=poly_shared_lockable>
+ class upgrade_lockable_adapter: public shared_lockable_adapter<Mutex, Base>
+ {
+ public:
+ typedef Mutex mutex_type;
+
+ void lock_upgrade()
+ {
+ this->mtx().lock_upgrade();
+ }
+
+ bool try_lock_upgrade()
+ {
+ return this->mtx().try_lock_upgrade();
+ }
+
+ void unlock_upgrade()
+ {
+ this->mtx().unlock_upgrade();
+ }
+
+ bool try_lock_upgrade_until(chrono::system_clock::time_point const & abs_time)
+ {
+ return this->mtx().try_lock_upgrade_until(abs_time);
+ }
+ bool try_lock_upgrade_until(chrono::steady_clock::time_point const & abs_time)
+ {
+ return this->mtx().try_lock_upgrade_until(abs_time);
+ }
+ bool try_lock_upgrade_for(chrono::nanoseconds const & rel_time)
+ {
+ return this->mtx().try_lock_upgrade_for(rel_time);
+ }
+
+ bool try_unlock_shared_and_lock()
+ {
+ return this->mtx().try_unlock_shared_and_lock();
+ }
+
+ bool try_unlock_shared_and_lock_until(chrono::system_clock::time_point const & abs_time)
+ {
+ return this->mtx().try_unlock_shared_and_lock_until(abs_time);
+ }
+ bool try_unlock_shared_and_lock_until(chrono::steady_clock::time_point const & abs_time)
+ {
+ return this->mtx().try_unlock_shared_and_lock_until(abs_time);
+ }
+ template <typename Rep, typename Period>
+ bool try_unlock_shared_and_lock_for(chrono::nanoseconds const & rel_time)
+ {
+ return this->mtx().try_unlock_shared_and_lock_for(rel_time);
+ }
+
+ void unlock_and_lock_shared()
+ {
+ this->mtx().unlock_and_lock_shared();
+ }
+
+ bool try_unlock_shared_and_lock_upgrade()
+ {
+ return this->mtx().try_unlock_shared_and_lock_upgrade();
+ }
+
+ bool try_unlock_shared_and_lock_upgrade_until(chrono::system_clock::time_point const & abs_time)
+ {
+ return this->mtx().try_unlock_shared_and_lock_upgrade_until(abs_time);
+ }
+ bool try_unlock_shared_and_lock_upgrade_until(chrono::steady_clock::time_point const & abs_time)
+ {
+ return this->mtx().try_unlock_shared_and_lock_upgrade_until(abs_time);
+ }
+ bool try_unlock_shared_and_lock_upgrade_for(chrono::nanoseconds const & rel_time)
+ {
+ return this->mtx().try_unlock_shared_and_lock_upgrade_for(rel_time);
+ }
+
+ void unlock_and_lock_upgrade()
+ {
+ this->mtx().unlock_and_lock_upgrade();
+ }
+
+ void unlock_upgrade_and_lock()
+ {
+ this->mtx().unlock_upgrade_and_lock();
+ }
+
+ bool try_unlock_upgrade_and_lock()
+ {
+ return this->mtx().try_unlock_upgrade_and_lock();
+ }
+ bool try_unlock_upgrade_and_lock_until(chrono::system_clock::time_point const & abs_time)
+ {
+ return this->mtx().try_unlock_upgrade_and_lock_until(abs_time);
+ }
+ bool try_unlock_upgrade_and_lock_until(chrono::steady_clock::time_point const & abs_time)
+ {
+ return this->mtx().try_unlock_upgrade_and_lock_until(abs_time);
+ }
+ bool try_unlock_upgrade_and_lock_for(chrono::nanoseconds const & rel_time)
+ {
+ return this->mtx().try_unlock_upgrade_and_lock_for(rel_time);
+ }
+
+ void unlock_upgrade_and_lock_shared()
+ {
+ this->mtx().unlock_upgrade_and_lock_shared();
+ }
+
+ };
+//]
+
+}
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/pthread/condition_variable.hpp b/src/third_party/boost-1.60.0/boost/thread/pthread/condition_variable.hpp
new file mode 100644
index 00000000000..a6033515915
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/pthread/condition_variable.hpp
@@ -0,0 +1,428 @@
+#ifndef BOOST_THREAD_CONDITION_VARIABLE_PTHREAD_HPP
+#define BOOST_THREAD_CONDITION_VARIABLE_PTHREAD_HPP
+// Distributed under the 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 2007-10 Anthony Williams
+// (C) Copyright 2011-2012 Vicente J. Botet Escriba
+
+#include <boost/thread/pthread/timespec.hpp>
+#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp>
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+#include <boost/thread/pthread/thread_data.hpp>
+#endif
+#include <boost/thread/pthread/condition_variable_fwd.hpp>
+#ifdef BOOST_THREAD_USES_CHRONO
+#include <boost/chrono/system_clocks.hpp>
+#include <boost/chrono/ceil.hpp>
+#endif
+#include <boost/thread/detail/delete.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ namespace this_thread
+ {
+ void BOOST_THREAD_DECL interruption_point();
+ }
+#endif
+
+ namespace thread_cv_detail
+ {
+ template<typename MutexType>
+ struct lock_on_exit
+ {
+ MutexType* m;
+
+ lock_on_exit():
+ m(0)
+ {}
+
+ void activate(MutexType& m_)
+ {
+ m_.unlock();
+ m=&m_;
+ }
+ ~lock_on_exit()
+ {
+ if(m)
+ {
+ m->lock();
+ }
+ }
+ };
+ }
+
+ inline void condition_variable::wait(unique_lock<mutex>& m)
+ {
+#if defined BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED
+ if(! m.owns_lock())
+ {
+ boost::throw_exception(condition_error(-1, "boost::condition_variable::wait() failed precondition mutex not owned"));
+ }
+#endif
+ int res=0;
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ thread_cv_detail::lock_on_exit<unique_lock<mutex> > guard;
+ detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
+ pthread_mutex_t* the_mutex = &internal_mutex;
+ guard.activate(m);
+#else
+ pthread_mutex_t* the_mutex = m.mutex()->native_handle();
+#endif
+ do {
+ res = pthread_cond_wait(&cond,the_mutex);
+ } while (res == EINTR);
+ }
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ this_thread::interruption_point();
+#endif
+ if(res)
+ {
+ boost::throw_exception(condition_error(res, "boost::condition_variable::wait failed in pthread_cond_wait"));
+ }
+ }
+
+ inline bool condition_variable::do_wait_until(
+ unique_lock<mutex>& m,
+ struct timespec const &timeout)
+ {
+#if defined BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED
+ if (!m.owns_lock())
+ {
+ boost::throw_exception(condition_error(EPERM, "boost::condition_variable::do_wait_until() failed precondition mutex not owned"));
+ }
+#endif
+ int cond_res;
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ thread_cv_detail::lock_on_exit<unique_lock<mutex> > guard;
+ detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
+ pthread_mutex_t* the_mutex = &internal_mutex;
+ guard.activate(m);
+#else
+ pthread_mutex_t* the_mutex = m.mutex()->native_handle();
+#endif
+ cond_res=pthread_cond_timedwait(&cond,the_mutex,&timeout);
+ }
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ this_thread::interruption_point();
+#endif
+ if(cond_res==ETIMEDOUT)
+ {
+ return false;
+ }
+ if(cond_res)
+ {
+ boost::throw_exception(condition_error(cond_res, "boost::condition_variable::do_wait_until failed in pthread_cond_timedwait"));
+ }
+ return true;
+ }
+
+ inline void condition_variable::notify_one() BOOST_NOEXCEPT
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
+#endif
+ BOOST_VERIFY(!pthread_cond_signal(&cond));
+ }
+
+ inline void condition_variable::notify_all() BOOST_NOEXCEPT
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
+#endif
+ BOOST_VERIFY(!pthread_cond_broadcast(&cond));
+ }
+
+ class condition_variable_any
+ {
+ pthread_mutex_t internal_mutex;
+ pthread_cond_t cond;
+
+ public:
+ BOOST_THREAD_NO_COPYABLE(condition_variable_any)
+ condition_variable_any()
+ {
+ int const res=pthread_mutex_init(&internal_mutex,NULL);
+ if(res)
+ {
+ boost::throw_exception(thread_resource_error(res, "boost::condition_variable_any::condition_variable_any() failed in pthread_mutex_init"));
+ }
+ int const res2 = detail::monotonic_pthread_cond_init(cond);
+ if(res2)
+ {
+ BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
+ boost::throw_exception(thread_resource_error(res2, "boost::condition_variable_any::condition_variable_any() failed in detail::monotonic_pthread_cond_init"));
+ }
+ }
+ ~condition_variable_any()
+ {
+ BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
+ BOOST_VERIFY(!pthread_cond_destroy(&cond));
+ }
+
+ template<typename lock_type>
+ void wait(lock_type& m)
+ {
+ int res=0;
+ {
+ thread_cv_detail::lock_on_exit<lock_type> guard;
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
+#else
+ boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex);
+#endif
+ guard.activate(m);
+ res=pthread_cond_wait(&cond,&internal_mutex);
+ }
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ this_thread::interruption_point();
+#endif
+ if(res)
+ {
+ boost::throw_exception(condition_error(res, "boost::condition_variable_any::wait() failed in pthread_cond_wait"));
+ }
+ }
+
+ template<typename lock_type,typename predicate_type>
+ void wait(lock_type& m,predicate_type pred)
+ {
+ while(!pred()) wait(m);
+ }
+
+#if defined BOOST_THREAD_USES_DATETIME
+ template<typename lock_type>
+ bool timed_wait(lock_type& m,boost::system_time const& abs_time)
+ {
+ struct timespec const timeout=detail::to_timespec(abs_time);
+ return do_wait_until(m, timeout);
+ }
+ template<typename lock_type>
+ bool timed_wait(lock_type& m,xtime const& abs_time)
+ {
+ return timed_wait(m,system_time(abs_time));
+ }
+
+ template<typename lock_type,typename duration_type>
+ bool timed_wait(lock_type& m,duration_type const& wait_duration)
+ {
+ return timed_wait(m,get_system_time()+wait_duration);
+ }
+
+ template<typename lock_type,typename predicate_type>
+ bool timed_wait(lock_type& m,boost::system_time const& abs_time, predicate_type pred)
+ {
+ while (!pred())
+ {
+ if(!timed_wait(m, abs_time))
+ return pred();
+ }
+ return true;
+ }
+
+ template<typename lock_type,typename predicate_type>
+ bool timed_wait(lock_type& m,xtime const& abs_time, predicate_type pred)
+ {
+ return timed_wait(m,system_time(abs_time),pred);
+ }
+
+ template<typename lock_type,typename duration_type,typename predicate_type>
+ bool timed_wait(lock_type& m,duration_type const& wait_duration,predicate_type pred)
+ {
+ return timed_wait(m,get_system_time()+wait_duration,pred);
+ }
+#endif
+#ifndef BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
+
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class lock_type,class Duration>
+ cv_status
+ wait_until(
+ lock_type& lock,
+ const chrono::time_point<chrono::system_clock, Duration>& t)
+ {
+ using namespace chrono;
+ typedef time_point<system_clock, nanoseconds> nano_sys_tmpt;
+ wait_until(lock,
+ nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch())));
+ return system_clock::now() < t ? cv_status::no_timeout :
+ cv_status::timeout;
+ }
+
+ template <class lock_type, class Clock, class Duration>
+ cv_status
+ wait_until(
+ lock_type& lock,
+ const chrono::time_point<Clock, Duration>& t)
+ {
+ using namespace chrono;
+ system_clock::time_point s_now = system_clock::now();
+ typename Clock::time_point c_now = Clock::now();
+ wait_until(lock, s_now + ceil<nanoseconds>(t - c_now));
+ return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout;
+ }
+
+ template <class lock_type, class Rep, class Period>
+ cv_status
+ wait_for(
+ lock_type& lock,
+ const chrono::duration<Rep, Period>& d)
+ {
+ using namespace chrono;
+ system_clock::time_point s_now = system_clock::now();
+ steady_clock::time_point c_now = steady_clock::now();
+ wait_until(lock, s_now + ceil<nanoseconds>(d));
+ return steady_clock::now() - c_now < d ? cv_status::no_timeout :
+ cv_status::timeout;
+
+ }
+
+ template <class lock_type>
+ cv_status wait_until(
+ lock_type& lk,
+ chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp)
+ {
+ using namespace chrono;
+ nanoseconds d = tp.time_since_epoch();
+ timespec ts = boost::detail::to_timespec(d);
+ if (do_wait_until(lk, ts)) return cv_status::no_timeout;
+ else return cv_status::timeout;
+ }
+#endif
+#else // defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
+#ifdef BOOST_THREAD_USES_CHRONO
+
+ template <class lock_type, class Duration>
+ cv_status
+ wait_until(
+ lock_type& lock,
+ const chrono::time_point<chrono::steady_clock, Duration>& t)
+ {
+ using namespace chrono;
+ typedef time_point<steady_clock, nanoseconds> nano_sys_tmpt;
+ wait_until(lock,
+ nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch())));
+ return steady_clock::now() < t ? cv_status::no_timeout :
+ cv_status::timeout;
+ }
+
+ template <class lock_type, class Clock, class Duration>
+ cv_status
+ wait_until(
+ lock_type& lock,
+ const chrono::time_point<Clock, Duration>& t)
+ {
+ using namespace chrono;
+ steady_clock::time_point s_now = steady_clock::now();
+ typename Clock::time_point c_now = Clock::now();
+ wait_until(lock, s_now + ceil<nanoseconds>(t - c_now));
+ return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout;
+ }
+
+ template <class lock_type, class Rep, class Period>
+ cv_status
+ wait_for(
+ lock_type& lock,
+ const chrono::duration<Rep, Period>& d)
+ {
+ using namespace chrono;
+ steady_clock::time_point c_now = steady_clock::now();
+ wait_until(lock, c_now + ceil<nanoseconds>(d));
+ return steady_clock::now() - c_now < d ? cv_status::no_timeout :
+ cv_status::timeout;
+ }
+
+ inline cv_status wait_until(
+ unique_lock<mutex>& lk,
+ chrono::time_point<chrono::steady_clock, chrono::nanoseconds> tp)
+ {
+ using namespace chrono;
+ nanoseconds d = tp.time_since_epoch();
+ timespec ts = boost::detail::to_timespec(d);
+ if (do_wait_until(lk, ts)) return cv_status::no_timeout;
+ else return cv_status::timeout;
+ }
+
+#endif
+#endif // defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
+
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class lock_type, class Clock, class Duration, class Predicate>
+ bool
+ wait_until(
+ lock_type& lock,
+ const chrono::time_point<Clock, Duration>& t,
+ Predicate pred)
+ {
+ while (!pred())
+ {
+ if (wait_until(lock, t) == cv_status::timeout)
+ return pred();
+ }
+ return true;
+ }
+
+ template <class lock_type, class Rep, class Period, class Predicate>
+ bool
+ wait_for(
+ lock_type& lock,
+ const chrono::duration<Rep, Period>& d,
+ Predicate pred)
+ {
+ return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred));
+ }
+#endif
+
+ void notify_one() BOOST_NOEXCEPT
+ {
+ boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
+ BOOST_VERIFY(!pthread_cond_signal(&cond));
+ }
+
+ void notify_all() BOOST_NOEXCEPT
+ {
+ boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
+ BOOST_VERIFY(!pthread_cond_broadcast(&cond));
+ }
+ private: // used by boost::thread::try_join_until
+
+ template <class lock_type>
+ inline bool do_wait_until(
+ lock_type& m,
+ struct timespec const &timeout)
+ {
+ int res=0;
+ {
+ thread_cv_detail::lock_on_exit<lock_type> guard;
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
+#else
+ boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex);
+#endif
+ guard.activate(m);
+ res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout);
+ }
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ this_thread::interruption_point();
+#endif
+ if(res==ETIMEDOUT)
+ {
+ return false;
+ }
+ if(res)
+ {
+ boost::throw_exception(condition_error(res, "boost::condition_variable_any::do_wait_until() failed in pthread_cond_timedwait"));
+ }
+ return true;
+ }
+ };
+
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/pthread/condition_variable_fwd.hpp b/src/third_party/boost-1.60.0/boost/thread/pthread/condition_variable_fwd.hpp
new file mode 100644
index 00000000000..1255eac59b7
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/pthread/condition_variable_fwd.hpp
@@ -0,0 +1,360 @@
+#ifndef BOOST_THREAD_PTHREAD_CONDITION_VARIABLE_FWD_HPP
+#define BOOST_THREAD_PTHREAD_CONDITION_VARIABLE_FWD_HPP
+// Distributed under the 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 2007-8 Anthony Williams
+// (C) Copyright 2011-2012 Vicente J. Botet Escriba
+
+#include <boost/assert.hpp>
+#include <boost/throw_exception.hpp>
+#include <pthread.h>
+#include <boost/thread/cv_status.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/thread_time.hpp>
+#include <boost/thread/pthread/timespec.hpp>
+#if defined BOOST_THREAD_USES_DATETIME
+#include <boost/thread/xtime.hpp>
+#endif
+#ifdef BOOST_THREAD_USES_CHRONO
+#include <boost/chrono/system_clocks.hpp>
+#include <boost/chrono/ceil.hpp>
+#endif
+#include <boost/thread/detail/delete.hpp>
+#include <boost/date_time/posix_time/posix_time_duration.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ namespace detail {
+ inline int monotonic_pthread_cond_init(pthread_cond_t& cond) {
+
+#ifdef BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
+ pthread_condattr_t attr;
+ int res = pthread_condattr_init(&attr);
+ if (res)
+ {
+ return res;
+ }
+ pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
+ res=pthread_cond_init(&cond,&attr);
+ pthread_condattr_destroy(&attr);
+ return res;
+#else
+ return pthread_cond_init(&cond,NULL);
+#endif
+
+ }
+ }
+
+ class condition_variable
+ {
+ private:
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ pthread_mutex_t internal_mutex;
+#endif
+ pthread_cond_t cond;
+
+ public:
+ //private: // used by boost::thread::try_join_until
+
+ inline bool do_wait_until(
+ unique_lock<mutex>& lock,
+ struct timespec const &timeout);
+
+ bool do_wait_for(
+ unique_lock<mutex>& lock,
+ struct timespec const &timeout)
+ {
+ return do_wait_until(lock, boost::detail::timespec_plus(timeout, boost::detail::timespec_now()));
+ }
+
+ public:
+ BOOST_THREAD_NO_COPYABLE(condition_variable)
+ condition_variable()
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ int res=pthread_mutex_init(&internal_mutex,NULL);
+ if(res)
+ {
+ boost::throw_exception(thread_resource_error(res, "boost::condition_variable::condition_variable() constructor failed in pthread_mutex_init"));
+ }
+#endif
+ res = detail::monotonic_pthread_cond_init(cond);
+ if (res)
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
+#endif
+ boost::throw_exception(thread_resource_error(res, "boost::condition_variable::condition_variable() constructor failed in detail::monotonic_pthread_cond_init"));
+ }
+ }
+ ~condition_variable()
+ {
+ int ret;
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ do {
+ ret = pthread_mutex_destroy(&internal_mutex);
+ } while (ret == EINTR);
+ BOOST_ASSERT(!ret);
+#endif
+ do {
+ ret = pthread_cond_destroy(&cond);
+ } while (ret == EINTR);
+ BOOST_ASSERT(!ret);
+ }
+
+ void wait(unique_lock<mutex>& m);
+
+ template<typename predicate_type>
+ void wait(unique_lock<mutex>& m,predicate_type pred)
+ {
+ while(!pred()) wait(m);
+ }
+
+#if defined BOOST_THREAD_USES_DATETIME
+ inline bool timed_wait(
+ unique_lock<mutex>& m,
+ boost::system_time const& abs_time)
+ {
+#if defined BOOST_THREAD_WAIT_BUG
+ struct timespec const timeout=detail::to_timespec(abs_time + BOOST_THREAD_WAIT_BUG);
+ return do_wait_until(m, timeout);
+#else
+ struct timespec const timeout=detail::to_timespec(abs_time);
+ return do_wait_until(m, timeout);
+#endif
+ }
+ bool timed_wait(
+ unique_lock<mutex>& m,
+ xtime const& abs_time)
+ {
+ return timed_wait(m,system_time(abs_time));
+ }
+
+ template<typename duration_type>
+ bool timed_wait(
+ unique_lock<mutex>& m,
+ duration_type const& wait_duration)
+ {
+ if (wait_duration.is_pos_infinity())
+ {
+ wait(m); // or do_wait(m,detail::timeout::sentinel());
+ return true;
+ }
+ if (wait_duration.is_special())
+ {
+ return true;
+ }
+ return timed_wait(m,get_system_time()+wait_duration);
+ }
+
+ template<typename predicate_type>
+ bool timed_wait(
+ unique_lock<mutex>& m,
+ boost::system_time const& abs_time,predicate_type pred)
+ {
+ while (!pred())
+ {
+ if(!timed_wait(m, abs_time))
+ return pred();
+ }
+ return true;
+ }
+
+ template<typename predicate_type>
+ bool timed_wait(
+ unique_lock<mutex>& m,
+ xtime const& abs_time,predicate_type pred)
+ {
+ return timed_wait(m,system_time(abs_time),pred);
+ }
+
+ template<typename duration_type,typename predicate_type>
+ bool timed_wait(
+ unique_lock<mutex>& m,
+ duration_type const& wait_duration,predicate_type pred)
+ {
+ if (wait_duration.is_pos_infinity())
+ {
+ while (!pred())
+ {
+ wait(m); // or do_wait(m,detail::timeout::sentinel());
+ }
+ return true;
+ }
+ if (wait_duration.is_special())
+ {
+ return pred();
+ }
+ return timed_wait(m,get_system_time()+wait_duration,pred);
+ }
+#endif
+
+#ifndef BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
+
+#ifdef BOOST_THREAD_USES_CHRONO
+
+ template <class Duration>
+ cv_status
+ wait_until(
+ unique_lock<mutex>& lock,
+ const chrono::time_point<chrono::system_clock, Duration>& t)
+ {
+ using namespace chrono;
+ typedef time_point<system_clock, nanoseconds> nano_sys_tmpt;
+ wait_until(lock,
+ nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch())));
+ return system_clock::now() < t ? cv_status::no_timeout :
+ cv_status::timeout;
+ }
+
+ template <class Clock, class Duration>
+ cv_status
+ wait_until(
+ unique_lock<mutex>& lock,
+ const chrono::time_point<Clock, Duration>& t)
+ {
+ using namespace chrono;
+ system_clock::time_point s_now = system_clock::now();
+ typename Clock::time_point c_now = Clock::now();
+ wait_until(lock, s_now + ceil<nanoseconds>(t - c_now));
+ return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout;
+ }
+
+
+
+ template <class Rep, class Period>
+ cv_status
+ wait_for(
+ unique_lock<mutex>& lock,
+ const chrono::duration<Rep, Period>& d)
+ {
+ using namespace chrono;
+ system_clock::time_point s_now = system_clock::now();
+ steady_clock::time_point c_now = steady_clock::now();
+ wait_until(lock, s_now + ceil<nanoseconds>(d));
+ return steady_clock::now() - c_now < d ? cv_status::no_timeout :
+ cv_status::timeout;
+
+ }
+
+ inline cv_status wait_until(
+ unique_lock<mutex>& lk,
+ chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp)
+ {
+ using namespace chrono;
+ nanoseconds d = tp.time_since_epoch();
+ timespec ts = boost::detail::to_timespec(d);
+ if (do_wait_until(lk, ts)) return cv_status::no_timeout;
+ else return cv_status::timeout;
+ }
+#endif
+
+#else // defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
+#ifdef BOOST_THREAD_USES_CHRONO
+
+ template <class Duration>
+ cv_status
+ wait_until(
+ unique_lock<mutex>& lock,
+ const chrono::time_point<chrono::steady_clock, Duration>& t)
+ {
+ using namespace chrono;
+ typedef time_point<steady_clock, nanoseconds> nano_sys_tmpt;
+ wait_until(lock,
+ nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch())));
+ return steady_clock::now() < t ? cv_status::no_timeout :
+ cv_status::timeout;
+ }
+
+ template <class Clock, class Duration>
+ cv_status
+ wait_until(
+ unique_lock<mutex>& lock,
+ const chrono::time_point<Clock, Duration>& t)
+ {
+ using namespace chrono;
+ steady_clock::time_point s_now = steady_clock::now();
+ typename Clock::time_point c_now = Clock::now();
+ wait_until(lock, s_now + ceil<nanoseconds>(t - c_now));
+ return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout;
+ }
+
+ template <class Rep, class Period>
+ cv_status
+ wait_for(
+ unique_lock<mutex>& lock,
+ const chrono::duration<Rep, Period>& d)
+ {
+ using namespace chrono;
+ steady_clock::time_point c_now = steady_clock::now();
+ wait_until(lock, c_now + ceil<nanoseconds>(d));
+ return steady_clock::now() - c_now < d ? cv_status::no_timeout :
+ cv_status::timeout;
+ }
+
+ inline cv_status wait_until(
+ unique_lock<mutex>& lk,
+ chrono::time_point<chrono::steady_clock, chrono::nanoseconds> tp)
+ {
+ using namespace chrono;
+ nanoseconds d = tp.time_since_epoch();
+ timespec ts = boost::detail::to_timespec(d);
+ if (do_wait_until(lk, ts)) return cv_status::no_timeout;
+ else return cv_status::timeout;
+ }
+#endif
+
+#endif // defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
+
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Clock, class Duration, class Predicate>
+ bool
+ wait_until(
+ unique_lock<mutex>& lock,
+ const chrono::time_point<Clock, Duration>& t,
+ Predicate pred)
+ {
+ while (!pred())
+ {
+ if (wait_until(lock, t) == cv_status::timeout)
+ return pred();
+ }
+ return true;
+ }
+
+ template <class Rep, class Period, class Predicate>
+ bool
+ wait_for(
+ unique_lock<mutex>& lock,
+ const chrono::duration<Rep, Period>& d,
+ Predicate pred)
+ {
+ return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred));
+ }
+#endif
+
+#define BOOST_THREAD_DEFINES_CONDITION_VARIABLE_NATIVE_HANDLE
+ typedef pthread_cond_t* native_handle_type;
+ native_handle_type native_handle()
+ {
+ return &cond;
+ }
+
+ void notify_one() BOOST_NOEXCEPT;
+ void notify_all() BOOST_NOEXCEPT;
+
+
+ };
+
+ BOOST_THREAD_DECL void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
+
+}
+
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/pthread/mutex.hpp b/src/third_party/boost-1.60.0/boost/thread/pthread/mutex.hpp
new file mode 100644
index 00000000000..9ac808b6f4a
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/pthread/mutex.hpp
@@ -0,0 +1,361 @@
+#ifndef BOOST_THREAD_PTHREAD_MUTEX_HPP
+#define BOOST_THREAD_PTHREAD_MUTEX_HPP
+// (C) Copyright 2007-8 Anthony Williams
+// (C) Copyright 2011,2012,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/thread/detail/config.hpp>
+#include <boost/assert.hpp>
+#include <pthread.h>
+#include <boost/throw_exception.hpp>
+#include <boost/core/ignore_unused.hpp>
+#include <boost/thread/exceptions.hpp>
+#if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
+#include <boost/thread/lock_types.hpp>
+#endif
+#include <boost/thread/thread_time.hpp>
+#include <boost/thread/xtime.hpp>
+#include <boost/assert.hpp>
+#include <errno.h>
+#include <boost/thread/pthread/timespec.hpp>
+#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp>
+#ifdef BOOST_THREAD_USES_CHRONO
+#include <boost/chrono/system_clocks.hpp>
+#include <boost/chrono/ceil.hpp>
+#endif
+#include <boost/thread/detail/delete.hpp>
+
+#if (defined(_POSIX_TIMEOUTS) && (_POSIX_TIMEOUTS-0)>=200112L) \
+ || (defined(__ANDROID__) && defined(__ANDROID_API__) && __ANDROID_API__ >= 21)
+#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
+#define BOOST_PTHREAD_HAS_TIMEDLOCK
+#endif
+#endif
+
+
+#include <boost/config/abi_prefix.hpp>
+
+#ifndef BOOST_THREAD_HAS_NO_EINTR_BUG
+#define BOOST_THREAD_HAS_EINTR_BUG
+#endif
+
+namespace boost
+{
+ namespace posix {
+#ifdef BOOST_THREAD_HAS_EINTR_BUG
+ BOOST_FORCEINLINE int pthread_mutex_destroy(pthread_mutex_t* m)
+ {
+ int ret;
+ do
+ {
+ ret = ::pthread_mutex_destroy(m);
+ } while (ret == EINTR);
+ return ret;
+ }
+ BOOST_FORCEINLINE int pthread_mutex_lock(pthread_mutex_t* m)
+ {
+ int ret;
+ do
+ {
+ ret = ::pthread_mutex_lock(m);
+ } while (ret == EINTR);
+ return ret;
+ }
+ BOOST_FORCEINLINE int pthread_mutex_unlock(pthread_mutex_t* m)
+ {
+ int ret;
+ do
+ {
+ ret = ::pthread_mutex_unlock(m);
+ } while (ret == EINTR);
+ return ret;
+ }
+#else
+ BOOST_FORCEINLINE int pthread_mutex_destroy(pthread_mutex_t* m)
+ {
+ return ::pthread_mutex_destroy(m);
+ }
+ BOOST_FORCEINLINE int pthread_mutex_lock(pthread_mutex_t* m)
+ {
+ return ::pthread_mutex_lock(m);
+ }
+ BOOST_FORCEINLINE int pthread_mutex_unlock(pthread_mutex_t* m)
+ {
+ return ::pthread_mutex_unlock(m);
+ }
+
+#endif
+
+ }
+ class mutex
+ {
+ private:
+ pthread_mutex_t m;
+ public:
+ BOOST_THREAD_NO_COPYABLE(mutex)
+
+ mutex()
+ {
+ int const res=pthread_mutex_init(&m,NULL);
+ if(res)
+ {
+ boost::throw_exception(thread_resource_error(res, "boost:: mutex constructor failed in pthread_mutex_init"));
+ }
+ }
+ ~mutex()
+ {
+ int const res = posix::pthread_mutex_destroy(&m);
+ boost::ignore_unused(res);
+ BOOST_ASSERT(!res);
+ }
+
+ void lock()
+ {
+ int res = posix::pthread_mutex_lock(&m);
+ if (res)
+ {
+ boost::throw_exception(lock_error(res,"boost: mutex lock failed in pthread_mutex_lock"));
+ }
+ }
+
+ void unlock()
+ {
+ int res = posix::pthread_mutex_unlock(&m);
+ (void)res;
+ BOOST_ASSERT(res == 0);
+// if (res)
+// {
+// boost::throw_exception(lock_error(res,"boost: mutex unlock failed in pthread_mutex_unlock"));
+// }
+ }
+
+ bool try_lock()
+ {
+ int res;
+ do
+ {
+ res = pthread_mutex_trylock(&m);
+ } while (res == EINTR);
+ if (res==EBUSY)
+ {
+ return false;
+ }
+
+ return !res;
+ }
+
+#define BOOST_THREAD_DEFINES_MUTEX_NATIVE_HANDLE
+ typedef pthread_mutex_t* native_handle_type;
+ native_handle_type native_handle()
+ {
+ return &m;
+ }
+
+#if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
+ typedef unique_lock<mutex> scoped_lock;
+ typedef detail::try_lock_wrapper<mutex> scoped_try_lock;
+#endif
+ };
+
+ typedef mutex try_mutex;
+
+ class timed_mutex
+ {
+ private:
+ pthread_mutex_t m;
+#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
+ pthread_cond_t cond;
+ bool is_locked;
+#endif
+ public:
+ BOOST_THREAD_NO_COPYABLE(timed_mutex)
+ timed_mutex()
+ {
+ int const res=pthread_mutex_init(&m,NULL);
+ if(res)
+ {
+ boost::throw_exception(thread_resource_error(res, "boost:: timed_mutex constructor failed in pthread_mutex_init"));
+ }
+#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
+ int const res2=pthread_cond_init(&cond,NULL);
+ if(res2)
+ {
+ BOOST_VERIFY(!posix::pthread_mutex_destroy(&m));
+ //BOOST_VERIFY(!pthread_mutex_destroy(&m));
+ boost::throw_exception(thread_resource_error(res2, "boost:: timed_mutex constructor failed in pthread_cond_init"));
+ }
+ is_locked=false;
+#endif
+ }
+ ~timed_mutex()
+ {
+ BOOST_VERIFY(!posix::pthread_mutex_destroy(&m));
+#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
+ BOOST_VERIFY(!pthread_cond_destroy(&cond));
+#endif
+ }
+
+#if defined BOOST_THREAD_USES_DATETIME
+ template<typename TimeDuration>
+ bool timed_lock(TimeDuration const & relative_time)
+ {
+ return timed_lock(get_system_time()+relative_time);
+ }
+ bool timed_lock(boost::xtime const & absolute_time)
+ {
+ return timed_lock(system_time(absolute_time));
+ }
+#endif
+#ifdef BOOST_PTHREAD_HAS_TIMEDLOCK
+ void lock()
+ {
+ int res = posix::pthread_mutex_lock(&m);
+ if (res)
+ {
+ boost::throw_exception(lock_error(res,"boost: mutex lock failed in pthread_mutex_lock"));
+ }
+ }
+
+ void unlock()
+ {
+ int res = posix::pthread_mutex_unlock(&m);
+ (void)res;
+ BOOST_ASSERT(res == 0);
+// if (res)
+// {
+// boost::throw_exception(lock_error(res,"boost: mutex unlock failed in pthread_mutex_unlock"));
+// }
+ }
+
+ bool try_lock()
+ {
+ int res;
+ do
+ {
+ res = pthread_mutex_trylock(&m);
+ } while (res == EINTR);
+ if (res==EBUSY)
+ {
+ return false;
+ }
+
+ return !res;
+ }
+
+
+ private:
+ bool do_try_lock_until(struct timespec const &timeout)
+ {
+ int const res=pthread_mutex_timedlock(&m,&timeout);
+ BOOST_ASSERT(!res || res==ETIMEDOUT);
+ return !res;
+ }
+ public:
+
+#else
+ void lock()
+ {
+ boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
+ while(is_locked)
+ {
+ BOOST_VERIFY(!pthread_cond_wait(&cond,&m));
+ }
+ is_locked=true;
+ }
+
+ void unlock()
+ {
+ boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
+ is_locked=false;
+ BOOST_VERIFY(!pthread_cond_signal(&cond));
+ }
+
+ bool try_lock()
+ {
+ boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
+ if(is_locked)
+ {
+ return false;
+ }
+ is_locked=true;
+ return true;
+ }
+
+ private:
+ bool do_try_lock_until(struct timespec const &timeout)
+ {
+ boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
+ while(is_locked)
+ {
+ int const cond_res=pthread_cond_timedwait(&cond,&m,&timeout);
+ if(cond_res==ETIMEDOUT)
+ {
+ return false;
+ }
+ BOOST_ASSERT(!cond_res);
+ }
+ is_locked=true;
+ return true;
+ }
+ public:
+#endif
+
+#if defined BOOST_THREAD_USES_DATETIME
+ bool timed_lock(system_time const & abs_time)
+ {
+ struct timespec const ts=boost::detail::to_timespec(abs_time);
+ return do_try_lock_until(ts);
+ }
+#endif
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_lock_until(chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool try_lock_until(const chrono::time_point<Clock, Duration>& t)
+ {
+ using namespace chrono;
+ system_clock::time_point s_now = system_clock::now();
+ typename Clock::time_point c_now = Clock::now();
+ return try_lock_until(s_now + ceil<nanoseconds>(t - c_now));
+ }
+ template <class Duration>
+ bool try_lock_until(const chrono::time_point<chrono::system_clock, Duration>& t)
+ {
+ using namespace chrono;
+ typedef time_point<system_clock, nanoseconds> nano_sys_tmpt;
+ return try_lock_until(nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch())));
+ }
+ bool try_lock_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp)
+ {
+ //using namespace chrono;
+ chrono::nanoseconds d = tp.time_since_epoch();
+ timespec ts = boost::detail::to_timespec(d);
+ return do_try_lock_until(ts);
+ }
+#endif
+
+#define BOOST_THREAD_DEFINES_TIMED_MUTEX_NATIVE_HANDLE
+ typedef pthread_mutex_t* native_handle_type;
+ native_handle_type native_handle()
+ {
+ return &m;
+ }
+
+#if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
+ typedef unique_lock<timed_mutex> scoped_timed_lock;
+ typedef detail::try_lock_wrapper<timed_mutex> scoped_try_lock;
+ typedef scoped_timed_lock scoped_lock;
+#endif
+ };
+
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/pthread/once.hpp b/src/third_party/boost-1.60.0/boost/thread/pthread/once.hpp
new file mode 100644
index 00000000000..0bef0387de7
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/pthread/once.hpp
@@ -0,0 +1,540 @@
+#ifndef BOOST_THREAD_PTHREAD_ONCE_HPP
+#define BOOST_THREAD_PTHREAD_ONCE_HPP
+
+// once.hpp
+//
+// (C) Copyright 2007-8 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)
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/detail/invoke.hpp>
+
+#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp>
+#include <boost/thread/detail/delete.hpp>
+#include <boost/core/no_exceptions_support.hpp>
+
+#include <boost/bind.hpp>
+#include <boost/assert.hpp>
+#include <boost/config/abi_prefix.hpp>
+
+#include <boost/cstdint.hpp>
+#include <pthread.h>
+#include <csignal>
+
+namespace boost
+{
+
+ struct once_flag;
+
+ #define BOOST_ONCE_INITIAL_FLAG_VALUE 0
+
+ namespace thread_detail
+ {
+ typedef boost::uint32_t uintmax_atomic_t;
+ #define BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_C2(value) value##u
+ #define BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_MAX_C BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_C2(~0)
+
+ }
+
+#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ template<typename Function, class ...ArgTypes>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(ArgTypes)... args);
+#else
+ template<typename Function>
+ inline void call_once(once_flag& flag, Function f);
+ template<typename Function, typename T1>
+ inline void call_once(once_flag& flag, Function f, T1 p1);
+ template<typename Function, typename T1, typename T2>
+ inline void call_once(once_flag& flag, Function f, T1 p1, T2 p2);
+ template<typename Function, typename T1, typename T2, typename T3>
+ inline void call_once(once_flag& flag, Function f, T1 p1, T2 p2, T3 p3);
+#endif
+
+ struct once_flag
+ {
+ BOOST_THREAD_NO_COPYABLE(once_flag)
+ BOOST_CONSTEXPR once_flag() BOOST_NOEXCEPT
+ : epoch(BOOST_ONCE_INITIAL_FLAG_VALUE)
+ {}
+ private:
+ volatile thread_detail::uintmax_atomic_t epoch;
+
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ template<typename Function, class ...ArgTypes>
+ friend void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(ArgTypes)... args);
+#else
+ template<typename Function>
+ friend void call_once(once_flag& flag, Function f);
+ template<typename Function, typename T1>
+ friend void call_once(once_flag& flag, Function f, T1 p1);
+ template<typename Function, typename T1, typename T2>
+ friend void call_once(once_flag& flag, Function f, T1 p1, T2 p2);
+ template<typename Function, typename T1, typename T2, typename T3>
+ friend void call_once(once_flag& flag, Function f, T1 p1, T2 p2, T3 p3);
+
+#endif
+
+ };
+
+#define BOOST_ONCE_INIT once_flag()
+
+#else // BOOST_THREAD_PROVIDES_ONCE_CXX11
+
+ struct once_flag
+ {
+ volatile thread_detail::uintmax_atomic_t epoch;
+ };
+
+#define BOOST_ONCE_INIT {BOOST_ONCE_INITIAL_FLAG_VALUE}
+#endif // BOOST_THREAD_PROVIDES_ONCE_CXX11
+
+
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+#define BOOST_THREAD_INVOKE_RET_VOID detail::invoke
+#define BOOST_THREAD_INVOKE_RET_VOID_CALL
+#elif defined BOOST_THREAD_PROVIDES_INVOKE_RET
+#define BOOST_THREAD_INVOKE_RET_VOID detail::invoke<void>
+#define BOOST_THREAD_INVOKE_RET_VOID_CALL
+#else
+#define BOOST_THREAD_INVOKE_RET_VOID boost::bind
+#define BOOST_THREAD_INVOKE_RET_VOID_CALL ()
+#endif
+
+ namespace thread_detail
+ {
+ BOOST_THREAD_DECL uintmax_atomic_t& get_once_per_thread_epoch();
+ BOOST_THREAD_DECL extern uintmax_atomic_t once_global_epoch;
+ BOOST_THREAD_DECL extern pthread_mutex_t once_epoch_mutex;
+ BOOST_THREAD_DECL extern pthread_cond_t once_epoch_cv;
+ }
+
+ // Based on Mike Burrows fast_pthread_once algorithm as described in
+ // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2444.html
+
+
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+
+
+ template<typename Function, class ...ArgTypes>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(ArgTypes)... args)
+ {
+ static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
+ static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
+ thread_detail::uintmax_atomic_t const epoch=flag.epoch;
+ thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
+
+ if(epoch<this_thread_epoch)
+ {
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
+
+ while(flag.epoch<=being_initialized)
+ {
+ if(flag.epoch==uninitialized_flag)
+ {
+ flag.epoch=being_initialized;
+ BOOST_TRY
+ {
+ pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
+ BOOST_THREAD_INVOKE_RET_VOID(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH (...)
+ {
+ flag.epoch=uninitialized_flag;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ flag.epoch=--thread_detail::once_global_epoch;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ }
+ else
+ {
+ while(flag.epoch==being_initialized)
+ {
+ BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
+ }
+ }
+ }
+ this_thread_epoch=thread_detail::once_global_epoch;
+
+ }
+ }
+#else
+ template<typename Function>
+ inline void call_once(once_flag& flag, Function f)
+ {
+ static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
+ static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
+ thread_detail::uintmax_atomic_t const epoch=flag.epoch;
+ thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
+
+ if(epoch<this_thread_epoch)
+ {
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
+
+ while(flag.epoch<=being_initialized)
+ {
+ if(flag.epoch==uninitialized_flag)
+ {
+ flag.epoch=being_initialized;
+ BOOST_TRY
+ {
+ pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
+ f();
+ }
+ BOOST_CATCH (...)
+ {
+ flag.epoch=uninitialized_flag;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ flag.epoch=--thread_detail::once_global_epoch;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ }
+ else
+ {
+ while(flag.epoch==being_initialized)
+ {
+ BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
+ }
+ }
+ }
+ this_thread_epoch=thread_detail::once_global_epoch;
+ }
+ }
+
+ template<typename Function, typename T1>
+ inline void call_once(once_flag& flag, Function f, T1 p1)
+ {
+ static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
+ static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
+ thread_detail::uintmax_atomic_t const epoch=flag.epoch;
+ thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
+
+ if(epoch<this_thread_epoch)
+ {
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
+
+ while(flag.epoch<=being_initialized)
+ {
+ if(flag.epoch==uninitialized_flag)
+ {
+ flag.epoch=being_initialized;
+ BOOST_TRY
+ {
+ pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
+ BOOST_THREAD_INVOKE_RET_VOID(f,p1) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH (...)
+ {
+ flag.epoch=uninitialized_flag;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ flag.epoch=--thread_detail::once_global_epoch;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ }
+ else
+ {
+ while(flag.epoch==being_initialized)
+ {
+ BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
+ }
+ }
+ }
+ this_thread_epoch=thread_detail::once_global_epoch;
+ }
+ }
+ template<typename Function, typename T1, typename T2>
+ inline void call_once(once_flag& flag, Function f, T1 p1, T2 p2)
+ {
+ static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
+ static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
+ thread_detail::uintmax_atomic_t const epoch=flag.epoch;
+ thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
+
+ if(epoch<this_thread_epoch)
+ {
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
+
+ while(flag.epoch<=being_initialized)
+ {
+ if(flag.epoch==uninitialized_flag)
+ {
+ flag.epoch=being_initialized;
+ BOOST_TRY
+ {
+ pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
+ BOOST_THREAD_INVOKE_RET_VOID(f,p1, p2) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH (...)
+ {
+ flag.epoch=uninitialized_flag;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ flag.epoch=--thread_detail::once_global_epoch;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ }
+ else
+ {
+ while(flag.epoch==being_initialized)
+ {
+ BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
+ }
+ }
+ }
+ this_thread_epoch=thread_detail::once_global_epoch;
+ }
+ }
+
+ template<typename Function, typename T1, typename T2, typename T3>
+ inline void call_once(once_flag& flag, Function f, T1 p1, T2 p2, T3 p3)
+ {
+ static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
+ static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
+ thread_detail::uintmax_atomic_t const epoch=flag.epoch;
+ thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
+
+ if(epoch<this_thread_epoch)
+ {
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
+
+ while(flag.epoch<=being_initialized)
+ {
+ if(flag.epoch==uninitialized_flag)
+ {
+ flag.epoch=being_initialized;
+ BOOST_TRY
+ {
+ pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
+ BOOST_THREAD_INVOKE_RET_VOID(f,p1, p2, p3) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH (...)
+ {
+ flag.epoch=uninitialized_flag;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ flag.epoch=--thread_detail::once_global_epoch;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ }
+ else
+ {
+ while(flag.epoch==being_initialized)
+ {
+ BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
+ }
+ }
+ }
+ this_thread_epoch=thread_detail::once_global_epoch;
+ }
+ }
+
+ template<typename Function>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f)
+ {
+ static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
+ static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
+ thread_detail::uintmax_atomic_t const epoch=flag.epoch;
+ thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
+
+ if(epoch<this_thread_epoch)
+ {
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
+
+ while(flag.epoch<=being_initialized)
+ {
+ if(flag.epoch==uninitialized_flag)
+ {
+ flag.epoch=being_initialized;
+ BOOST_TRY
+ {
+ pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
+ f();
+ }
+ BOOST_CATCH (...)
+ {
+ flag.epoch=uninitialized_flag;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ flag.epoch=--thread_detail::once_global_epoch;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ }
+ else
+ {
+ while(flag.epoch==being_initialized)
+ {
+ BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
+ }
+ }
+ }
+ this_thread_epoch=thread_detail::once_global_epoch;
+ }
+ }
+
+ template<typename Function, typename T1>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1)
+ {
+ static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
+ static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
+ thread_detail::uintmax_atomic_t const epoch=flag.epoch;
+ thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
+
+ if(epoch<this_thread_epoch)
+ {
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
+
+ while(flag.epoch<=being_initialized)
+ {
+ if(flag.epoch==uninitialized_flag)
+ {
+ flag.epoch=being_initialized;
+ BOOST_TRY
+ {
+ pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
+ BOOST_THREAD_INVOKE_RET_VOID(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<T1>(p1))
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH (...)
+ {
+ flag.epoch=uninitialized_flag;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ flag.epoch=--thread_detail::once_global_epoch;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ }
+ else
+ {
+ while(flag.epoch==being_initialized)
+ {
+ BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
+ }
+ }
+ }
+ this_thread_epoch=thread_detail::once_global_epoch;
+ }
+ }
+ template<typename Function, typename T1, typename T2>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2)
+ {
+ static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
+ static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
+ thread_detail::uintmax_atomic_t const epoch=flag.epoch;
+ thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
+
+ if(epoch<this_thread_epoch)
+ {
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
+
+ while(flag.epoch<=being_initialized)
+ {
+ if(flag.epoch==uninitialized_flag)
+ {
+ flag.epoch=being_initialized;
+ BOOST_TRY
+ {
+ pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
+ BOOST_THREAD_INVOKE_RET_VOID(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
+ thread_detail::decay_copy(boost::forward<T1>(p2))
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH (...)
+ {
+ flag.epoch=uninitialized_flag;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ flag.epoch=--thread_detail::once_global_epoch;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ }
+ else
+ {
+ while(flag.epoch==being_initialized)
+ {
+ BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
+ }
+ }
+ }
+ this_thread_epoch=thread_detail::once_global_epoch;
+ }
+ }
+
+ template<typename Function, typename T1, typename T2, typename T3>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2, BOOST_THREAD_RV_REF(T3) p3)
+ {
+ static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
+ static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
+ thread_detail::uintmax_atomic_t const epoch=flag.epoch;
+ thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
+
+ if(epoch<this_thread_epoch)
+ {
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
+
+ while(flag.epoch<=being_initialized)
+ {
+ if(flag.epoch==uninitialized_flag)
+ {
+ flag.epoch=being_initialized;
+ BOOST_TRY
+ {
+ pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
+ BOOST_THREAD_INVOKE_RET_VOID(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
+ thread_detail::decay_copy(boost::forward<T1>(p2)),
+ thread_detail::decay_copy(boost::forward<T1>(p3))
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH (...)
+ {
+ flag.epoch=uninitialized_flag;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ flag.epoch=--thread_detail::once_global_epoch;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ }
+ else
+ {
+ while(flag.epoch==being_initialized)
+ {
+ BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
+ }
+ }
+ }
+ this_thread_epoch=thread_detail::once_global_epoch;
+ }
+ }
+
+#endif
+
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/pthread/once_atomic.hpp b/src/third_party/boost-1.60.0/boost/thread/pthread/once_atomic.hpp
new file mode 100644
index 00000000000..c54a35c5413
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/pthread/once_atomic.hpp
@@ -0,0 +1,313 @@
+#ifndef BOOST_THREAD_PTHREAD_ONCE_ATOMIC_HPP
+#define BOOST_THREAD_PTHREAD_ONCE_ATOMIC_HPP
+
+// once.hpp
+//
+// (C) Copyright 2013 Andrey Semashev
+// (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)
+
+#include <boost/thread/detail/config.hpp>
+
+#include <boost/cstdint.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/detail/invoke.hpp>
+#include <boost/core/no_exceptions_support.hpp>
+#include <boost/bind.hpp>
+#include <boost/atomic.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+
+ struct once_flag;
+
+ namespace thread_detail
+ {
+
+#if BOOST_ATOMIC_INT_LOCK_FREE == 2
+ typedef unsigned int atomic_int_type;
+#elif BOOST_ATOMIC_SHORT_LOCK_FREE == 2
+ typedef unsigned short atomic_int_type;
+#elif BOOST_ATOMIC_CHAR_LOCK_FREE == 2
+ typedef unsigned char atomic_int_type;
+#elif BOOST_ATOMIC_LONG_LOCK_FREE == 2
+ typedef unsigned long atomic_int_type;
+#elif defined(BOOST_HAS_LONG_LONG) && BOOST_ATOMIC_LLONG_LOCK_FREE == 2
+ typedef ulong_long_type atomic_int_type;
+#else
+ // All tested integer types are not atomic, the spinlock pool will be used
+ typedef unsigned int atomic_int_type;
+#endif
+
+ typedef boost::atomic<atomic_int_type> atomic_type;
+
+ BOOST_THREAD_DECL bool enter_once_region(once_flag& flag) BOOST_NOEXCEPT;
+ BOOST_THREAD_DECL void commit_once_region(once_flag& flag) BOOST_NOEXCEPT;
+ BOOST_THREAD_DECL void rollback_once_region(once_flag& flag) BOOST_NOEXCEPT;
+ inline atomic_type& get_atomic_storage(once_flag& flag) BOOST_NOEXCEPT;
+ }
+
+#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11
+
+ struct once_flag
+ {
+ BOOST_THREAD_NO_COPYABLE(once_flag)
+ BOOST_CONSTEXPR once_flag() BOOST_NOEXCEPT : storage(0)
+ {
+ }
+
+ private:
+ thread_detail::atomic_type storage;
+
+ friend BOOST_THREAD_DECL bool thread_detail::enter_once_region(once_flag& flag) BOOST_NOEXCEPT;
+ friend BOOST_THREAD_DECL void thread_detail::commit_once_region(once_flag& flag) BOOST_NOEXCEPT;
+ friend BOOST_THREAD_DECL void thread_detail::rollback_once_region(once_flag& flag) BOOST_NOEXCEPT;
+ friend thread_detail::atomic_type& thread_detail::get_atomic_storage(once_flag& flag) BOOST_NOEXCEPT;
+ };
+
+#define BOOST_ONCE_INIT boost::once_flag()
+
+ namespace thread_detail
+ {
+ inline atomic_type& get_atomic_storage(once_flag& flag) BOOST_NOEXCEPT
+ {
+ //return reinterpret_cast< atomic_type& >(flag.storage);
+ return flag.storage;
+ }
+ }
+
+#else // BOOST_THREAD_PROVIDES_ONCE_CXX11
+ struct once_flag
+ {
+ // The thread_detail::atomic_int_type storage is marked
+ // with this attribute in order to let the compiler know that it will alias this member
+ // and silence compilation warnings.
+ BOOST_THREAD_ATTRIBUTE_MAY_ALIAS thread_detail::atomic_int_type storage;
+ };
+
+ #define BOOST_ONCE_INIT {0}
+
+ namespace thread_detail
+ {
+ inline atomic_type& get_atomic_storage(once_flag& flag) BOOST_NOEXCEPT
+ {
+ return reinterpret_cast< atomic_type& >(flag.storage);
+ }
+
+ }
+
+#endif // BOOST_THREAD_PROVIDES_ONCE_CXX11
+
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+#define BOOST_THREAD_INVOKE_RET_VOID detail::invoke
+#define BOOST_THREAD_INVOKE_RET_VOID_CALL
+#elif defined BOOST_THREAD_PROVIDES_INVOKE_RET
+#define BOOST_THREAD_INVOKE_RET_VOID detail::invoke<void>
+#define BOOST_THREAD_INVOKE_RET_VOID_CALL
+#else
+#define BOOST_THREAD_INVOKE_RET_VOID boost::bind
+#define BOOST_THREAD_INVOKE_RET_VOID_CALL ()
+#endif
+
+
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+
+ template<typename Function, class ...ArgTypes>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(ArgTypes)... args)
+ {
+ if (thread_detail::enter_once_region(flag))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH (...)
+ {
+ thread_detail::rollback_once_region(flag);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ thread_detail::commit_once_region(flag);
+ }
+ }
+#else
+ template<typename Function>
+ inline void call_once(once_flag& flag, Function f)
+ {
+ if (thread_detail::enter_once_region(flag))
+ {
+ BOOST_TRY
+ {
+ f();
+ }
+ BOOST_CATCH (...)
+ {
+ thread_detail::rollback_once_region(flag);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ thread_detail::commit_once_region(flag);
+ }
+ }
+
+ template<typename Function, typename T1>
+ inline void call_once(once_flag& flag, Function f, T1 p1)
+ {
+ if (thread_detail::enter_once_region(flag))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(f, p1) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH (...)
+ {
+ thread_detail::rollback_once_region(flag);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ thread_detail::commit_once_region(flag);
+ }
+ }
+
+ template<typename Function, typename T1, typename T2>
+ inline void call_once(once_flag& flag, Function f, T1 p1, T2 p2)
+ {
+ if (thread_detail::enter_once_region(flag))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(f, p1, p2) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH (...)
+ {
+ thread_detail::rollback_once_region(flag);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ thread_detail::commit_once_region(flag);
+ }
+ }
+
+ template<typename Function, typename T1, typename T2, typename T3>
+ inline void call_once(once_flag& flag, Function f, T1 p1, T2 p2, T3 p3)
+ {
+ if (thread_detail::enter_once_region(flag))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(f, p1, p2, p3) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH (...)
+ {
+ thread_detail::rollback_once_region(flag);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ thread_detail::commit_once_region(flag);
+ }
+ }
+#if !(defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x5130))
+ template<typename Function>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f)
+ {
+ if (thread_detail::enter_once_region(flag))
+ {
+ BOOST_TRY
+ {
+ f();
+ }
+ BOOST_CATCH (...)
+ {
+ thread_detail::rollback_once_region(flag);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ thread_detail::commit_once_region(flag);
+ }
+ }
+
+ template<typename Function, typename T1>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1)
+ {
+ if (thread_detail::enter_once_region(flag))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<T1>(p1))
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH (...)
+ {
+ thread_detail::rollback_once_region(flag);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ thread_detail::commit_once_region(flag);
+ }
+ }
+ template<typename Function, typename T1, typename T2>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2)
+ {
+ if (thread_detail::enter_once_region(flag))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
+ thread_detail::decay_copy(boost::forward<T1>(p2))
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH (...)
+ {
+ thread_detail::rollback_once_region(flag);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ thread_detail::commit_once_region(flag);
+ }
+ }
+ template<typename Function, typename T1, typename T2, typename T3>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2, BOOST_THREAD_RV_REF(T3) p3)
+ {
+ if (thread_detail::enter_once_region(flag))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
+ thread_detail::decay_copy(boost::forward<T1>(p2)),
+ thread_detail::decay_copy(boost::forward<T1>(p3))
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+
+ }
+ BOOST_CATCH (...)
+ {
+ thread_detail::rollback_once_region(flag);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ thread_detail::commit_once_region(flag);
+ }
+ }
+
+#endif // __SUNPRO_CC
+
+#endif
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
+
diff --git a/src/third_party/boost-1.60.0/boost/thread/pthread/pthread_mutex_scoped_lock.hpp b/src/third_party/boost-1.60.0/boost/thread/pthread/pthread_mutex_scoped_lock.hpp
new file mode 100644
index 00000000000..cdbf8c67408
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/pthread/pthread_mutex_scoped_lock.hpp
@@ -0,0 +1,64 @@
+#ifndef BOOST_PTHREAD_MUTEX_SCOPED_LOCK_HPP
+#define BOOST_PTHREAD_MUTEX_SCOPED_LOCK_HPP
+// (C) Copyright 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)
+
+#include <pthread.h>
+#include <boost/assert.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ namespace pthread
+ {
+ class pthread_mutex_scoped_lock
+ {
+ pthread_mutex_t* m;
+ bool locked;
+ public:
+ explicit pthread_mutex_scoped_lock(pthread_mutex_t* m_):
+ m(m_),locked(true)
+ {
+ BOOST_VERIFY(!pthread_mutex_lock(m));
+ }
+ void unlock()
+ {
+ BOOST_VERIFY(!pthread_mutex_unlock(m));
+ locked=false;
+ }
+
+ ~pthread_mutex_scoped_lock()
+ {
+ if(locked)
+ {
+ unlock();
+ }
+ }
+
+ };
+
+ class pthread_mutex_scoped_unlock
+ {
+ pthread_mutex_t* m;
+ public:
+ explicit pthread_mutex_scoped_unlock(pthread_mutex_t* m_):
+ m(m_)
+ {
+ BOOST_VERIFY(!pthread_mutex_unlock(m));
+ }
+ ~pthread_mutex_scoped_unlock()
+ {
+ BOOST_VERIFY(!pthread_mutex_lock(m));
+ }
+
+ };
+ }
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/pthread/recursive_mutex.hpp b/src/third_party/boost-1.60.0/boost/thread/pthread/recursive_mutex.hpp
new file mode 100644
index 00000000000..4caae0b5df9
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/pthread/recursive_mutex.hpp
@@ -0,0 +1,404 @@
+#ifndef BOOST_THREAD_PTHREAD_RECURSIVE_MUTEX_HPP
+#define BOOST_THREAD_PTHREAD_RECURSIVE_MUTEX_HPP
+// (C) Copyright 2007-8 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)
+
+#include <pthread.h>
+#include <boost/throw_exception.hpp>
+#include <boost/thread/exceptions.hpp>
+#if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
+#include <boost/thread/lock_types.hpp>
+#endif
+#include <boost/thread/thread_time.hpp>
+#include <boost/assert.hpp>
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+#include <boost/date_time/posix_time/conversion.hpp>
+#include <errno.h>
+#include <boost/thread/pthread/timespec.hpp>
+#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp>
+#ifdef BOOST_THREAD_USES_CHRONO
+#include <boost/chrono/system_clocks.hpp>
+#include <boost/chrono/ceil.hpp>
+#endif
+#include <boost/thread/detail/delete.hpp>
+
+#if (defined _POSIX_TIMEOUTS && (_POSIX_TIMEOUTS-0)>=200112L) \
+ || (defined __ANDROID__ && defined __ANDROID_API__ && __ANDROID_API__ >= 21)
+#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
+#define BOOST_PTHREAD_HAS_TIMEDLOCK
+#endif
+#endif
+
+#if defined BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE \
+ || defined __ANDROID__
+#define BOOST_THREAD_HAS_PTHREAD_MUTEXATTR_SETTYPE
+#endif
+
+#if defined BOOST_THREAD_HAS_PTHREAD_MUTEXATTR_SETTYPE && defined BOOST_PTHREAD_HAS_TIMEDLOCK
+#define BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK
+#endif
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ class recursive_mutex
+ {
+ private:
+ pthread_mutex_t m;
+#ifndef BOOST_THREAD_HAS_PTHREAD_MUTEXATTR_SETTYPE
+ pthread_cond_t cond;
+ bool is_locked;
+ pthread_t owner;
+ unsigned count;
+#endif
+ public:
+ BOOST_THREAD_NO_COPYABLE(recursive_mutex)
+ recursive_mutex()
+ {
+#ifdef BOOST_THREAD_HAS_PTHREAD_MUTEXATTR_SETTYPE
+ pthread_mutexattr_t attr;
+
+ int const init_attr_res=pthread_mutexattr_init(&attr);
+ if(init_attr_res)
+ {
+ boost::throw_exception(thread_resource_error(init_attr_res, "boost:: recursive_mutex constructor failed in pthread_mutexattr_init"));
+ }
+ int const set_attr_res=pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE);
+ if(set_attr_res)
+ {
+ BOOST_VERIFY(!pthread_mutexattr_destroy(&attr));
+ boost::throw_exception(thread_resource_error(set_attr_res, "boost:: recursive_mutex constructor failed in pthread_mutexattr_settype"));
+ }
+
+ int const res=pthread_mutex_init(&m,&attr);
+ if(res)
+ {
+ BOOST_VERIFY(!pthread_mutexattr_destroy(&attr));
+ boost::throw_exception(thread_resource_error(res, "boost:: recursive_mutex constructor failed in pthread_mutex_init"));
+ }
+ BOOST_VERIFY(!pthread_mutexattr_destroy(&attr));
+#else
+ int const res=pthread_mutex_init(&m,NULL);
+ if(res)
+ {
+ boost::throw_exception(thread_resource_error(res, "boost:: recursive_mutex constructor failed in pthread_mutex_init"));
+ }
+ int const res2=pthread_cond_init(&cond,NULL);
+ if(res2)
+ {
+ BOOST_VERIFY(!pthread_mutex_destroy(&m));
+ boost::throw_exception(thread_resource_error(res2, "boost:: recursive_mutex constructor failed in pthread_cond_init"));
+ }
+ is_locked=false;
+ count=0;
+#endif
+ }
+ ~recursive_mutex()
+ {
+ BOOST_VERIFY(!pthread_mutex_destroy(&m));
+#ifndef BOOST_THREAD_HAS_PTHREAD_MUTEXATTR_SETTYPE
+ BOOST_VERIFY(!pthread_cond_destroy(&cond));
+#endif
+ }
+
+#ifdef BOOST_THREAD_HAS_PTHREAD_MUTEXATTR_SETTYPE
+ void lock()
+ {
+ BOOST_VERIFY(!pthread_mutex_lock(&m));
+ }
+
+ void unlock()
+ {
+ BOOST_VERIFY(!pthread_mutex_unlock(&m));
+ }
+
+ bool try_lock() BOOST_NOEXCEPT
+ {
+ int const res=pthread_mutex_trylock(&m);
+ BOOST_ASSERT(!res || res==EBUSY);
+ return !res;
+ }
+#define BOOST_THREAD_DEFINES_RECURSIVE_MUTEX_NATIVE_HANDLE
+ typedef pthread_mutex_t* native_handle_type;
+ native_handle_type native_handle()
+ {
+ return &m;
+ }
+
+#else
+ void lock()
+ {
+ boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
+ if(is_locked && pthread_equal(owner,pthread_self()))
+ {
+ ++count;
+ return;
+ }
+
+ while(is_locked)
+ {
+ BOOST_VERIFY(!pthread_cond_wait(&cond,&m));
+ }
+ is_locked=true;
+ ++count;
+ owner=pthread_self();
+ }
+
+ void unlock()
+ {
+ boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
+ if(!--count)
+ {
+ is_locked=false;
+ }
+ BOOST_VERIFY(!pthread_cond_signal(&cond));
+ }
+
+ bool try_lock()
+ {
+ boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
+ if(is_locked && !pthread_equal(owner,pthread_self()))
+ {
+ return false;
+ }
+ is_locked=true;
+ ++count;
+ owner=pthread_self();
+ return true;
+ }
+
+#endif
+
+#if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
+ typedef unique_lock<recursive_mutex> scoped_lock;
+ typedef detail::try_lock_wrapper<recursive_mutex> scoped_try_lock;
+#endif
+ };
+
+ typedef recursive_mutex recursive_try_mutex;
+
+ class recursive_timed_mutex
+ {
+ private:
+ pthread_mutex_t m;
+#ifndef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK
+ pthread_cond_t cond;
+ bool is_locked;
+ pthread_t owner;
+ unsigned count;
+#endif
+ public:
+ BOOST_THREAD_NO_COPYABLE(recursive_timed_mutex)
+ recursive_timed_mutex()
+ {
+#ifdef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK
+ pthread_mutexattr_t attr;
+
+ int const init_attr_res=pthread_mutexattr_init(&attr);
+ if(init_attr_res)
+ {
+ boost::throw_exception(thread_resource_error(init_attr_res, "boost:: recursive_timed_mutex constructor failed in pthread_mutexattr_init"));
+ }
+ int const set_attr_res=pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE);
+ if(set_attr_res)
+ {
+ boost::throw_exception(thread_resource_error(set_attr_res, "boost:: recursive_timed_mutex constructor failed in pthread_mutexattr_settype"));
+ }
+
+ int const res=pthread_mutex_init(&m,&attr);
+ if(res)
+ {
+ BOOST_VERIFY(!pthread_mutexattr_destroy(&attr));
+ boost::throw_exception(thread_resource_error(res, "boost:: recursive_timed_mutex constructor failed in pthread_mutex_init"));
+ }
+ BOOST_VERIFY(!pthread_mutexattr_destroy(&attr));
+#else
+ int const res=pthread_mutex_init(&m,NULL);
+ if(res)
+ {
+ boost::throw_exception(thread_resource_error(res, "boost:: recursive_timed_mutex constructor failed in pthread_mutex_init"));
+ }
+ int const res2=pthread_cond_init(&cond,NULL);
+ if(res2)
+ {
+ BOOST_VERIFY(!pthread_mutex_destroy(&m));
+ boost::throw_exception(thread_resource_error(res2, "boost:: recursive_timed_mutex constructor failed in pthread_cond_init"));
+ }
+ is_locked=false;
+ count=0;
+#endif
+ }
+ ~recursive_timed_mutex()
+ {
+ BOOST_VERIFY(!pthread_mutex_destroy(&m));
+#ifndef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK
+ BOOST_VERIFY(!pthread_cond_destroy(&cond));
+#endif
+ }
+
+#if defined BOOST_THREAD_USES_DATETIME
+ template<typename TimeDuration>
+ bool timed_lock(TimeDuration const & relative_time)
+ {
+ return timed_lock(get_system_time()+relative_time);
+ }
+#endif
+
+#ifdef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK
+ void lock()
+ {
+ BOOST_VERIFY(!pthread_mutex_lock(&m));
+ }
+
+ void unlock()
+ {
+ BOOST_VERIFY(!pthread_mutex_unlock(&m));
+ }
+
+ bool try_lock()
+ {
+ int const res=pthread_mutex_trylock(&m);
+ BOOST_ASSERT(!res || res==EBUSY);
+ return !res;
+ }
+ private:
+ bool do_try_lock_until(struct timespec const &timeout)
+ {
+ int const res=pthread_mutex_timedlock(&m,&timeout);
+ BOOST_ASSERT(!res || res==ETIMEDOUT);
+ return !res;
+ }
+
+ public:
+
+#else
+ void lock()
+ {
+ boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
+ if(is_locked && pthread_equal(owner,pthread_self()))
+ {
+ ++count;
+ return;
+ }
+
+ while(is_locked)
+ {
+ BOOST_VERIFY(!pthread_cond_wait(&cond,&m));
+ }
+ is_locked=true;
+ ++count;
+ owner=pthread_self();
+ }
+
+ void unlock()
+ {
+ boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
+ if(!--count)
+ {
+ is_locked=false;
+ }
+ BOOST_VERIFY(!pthread_cond_signal(&cond));
+ }
+
+ bool try_lock() BOOST_NOEXCEPT
+ {
+ boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
+ if(is_locked && !pthread_equal(owner,pthread_self()))
+ {
+ return false;
+ }
+ is_locked=true;
+ ++count;
+ owner=pthread_self();
+ return true;
+ }
+
+ private:
+ bool do_try_lock_until(struct timespec const &timeout)
+ {
+ boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
+ if(is_locked && pthread_equal(owner,pthread_self()))
+ {
+ ++count;
+ return true;
+ }
+ while(is_locked)
+ {
+ int const cond_res=pthread_cond_timedwait(&cond,&m,&timeout);
+ if(cond_res==ETIMEDOUT)
+ {
+ return false;
+ }
+ BOOST_ASSERT(!cond_res);
+ }
+ is_locked=true;
+ ++count;
+ owner=pthread_self();
+ return true;
+ }
+ public:
+
+#endif
+
+#if defined BOOST_THREAD_USES_DATETIME
+ bool timed_lock(system_time const & abs_time)
+ {
+ struct timespec const ts=detail::to_timespec(abs_time);
+ return do_try_lock_until(ts);
+ }
+#endif
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_lock_until(chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool try_lock_until(const chrono::time_point<Clock, Duration>& t)
+ {
+ using namespace chrono;
+ system_clock::time_point s_now = system_clock::now();
+ typename Clock::time_point c_now = Clock::now();
+ return try_lock_until(s_now + ceil<nanoseconds>(t - c_now));
+ }
+ template <class Duration>
+ bool try_lock_until(const chrono::time_point<chrono::system_clock, Duration>& t)
+ {
+ using namespace chrono;
+ typedef time_point<system_clock, nanoseconds> nano_sys_tmpt;
+ return try_lock_until(nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch())));
+ }
+ bool try_lock_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp)
+ {
+ //using namespace chrono;
+ chrono::nanoseconds d = tp.time_since_epoch();
+ timespec ts = boost::detail::to_timespec(d);
+ return do_try_lock_until(ts);
+ }
+#endif
+
+#define BOOST_THREAD_DEFINES_RECURSIVE_TIMED_MUTEX_NATIVE_HANDLE
+ typedef pthread_mutex_t* native_handle_type;
+ native_handle_type native_handle()
+ {
+ return &m;
+ }
+
+#if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
+ typedef unique_lock<recursive_timed_mutex> scoped_timed_lock;
+ typedef detail::try_lock_wrapper<recursive_timed_mutex> scoped_try_lock;
+ typedef scoped_timed_lock scoped_lock;
+#endif
+ };
+
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/pthread/shared_mutex.hpp b/src/third_party/boost-1.60.0/boost/thread/pthread/shared_mutex.hpp
new file mode 100644
index 00000000000..458d6c83613
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/pthread/shared_mutex.hpp
@@ -0,0 +1,716 @@
+#ifndef BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP
+#define BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP
+
+// (C) Copyright 2006-8 Anthony Williams
+// (C) Copyright 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)
+
+#include <boost/assert.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition_variable.hpp>
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+#include <boost/thread/detail/thread_interruption.hpp>
+#endif
+#ifdef BOOST_THREAD_USES_CHRONO
+#include <boost/chrono/system_clocks.hpp>
+#include <boost/chrono/ceil.hpp>
+#endif
+#include <boost/thread/detail/delete.hpp>
+#include <boost/assert.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ class shared_mutex
+ {
+ private:
+ class state_data
+ {
+ public:
+ state_data () :
+ shared_count(0),
+ exclusive(false),
+ upgrade(false),
+ exclusive_waiting_blocked(false)
+ {}
+
+ void assert_free() const
+ {
+ BOOST_ASSERT( ! exclusive );
+ BOOST_ASSERT( ! upgrade );
+ BOOST_ASSERT( shared_count==0 );
+ }
+
+ void assert_locked() const
+ {
+ BOOST_ASSERT( exclusive );
+ BOOST_ASSERT( shared_count==0 );
+ BOOST_ASSERT( ! upgrade );
+ }
+
+ void assert_lock_shared () const
+ {
+ BOOST_ASSERT( ! exclusive );
+ BOOST_ASSERT( shared_count>0 );
+ //BOOST_ASSERT( (! upgrade) || (shared_count>1));
+ // if upgraded there are at least 2 threads sharing the mutex,
+ // except when unlock_upgrade_and_lock has decreased the number of readers but has not taken yet exclusive ownership.
+ }
+
+ void assert_lock_upgraded () const
+ {
+ BOOST_ASSERT( ! exclusive );
+ BOOST_ASSERT( upgrade );
+ BOOST_ASSERT( shared_count>0 );
+ }
+
+ void assert_lock_not_upgraded () const
+ {
+ BOOST_ASSERT( ! upgrade );
+ }
+
+ bool can_lock () const
+ {
+ return ! (shared_count || exclusive);
+ }
+
+ void exclusive_blocked (bool blocked)
+ {
+ exclusive_waiting_blocked = blocked;
+ }
+
+ void lock ()
+ {
+ exclusive = true;
+ }
+
+ void unlock ()
+ {
+ exclusive = false;
+ exclusive_waiting_blocked = false;
+ }
+
+ bool can_lock_shared () const
+ {
+ return ! (exclusive || exclusive_waiting_blocked);
+ }
+
+ bool more_shared () const
+ {
+ return shared_count > 0 ;
+ }
+ unsigned get_shared_count () const
+ {
+ return shared_count ;
+ }
+ unsigned lock_shared ()
+ {
+ return ++shared_count;
+ }
+
+
+ void unlock_shared ()
+ {
+ --shared_count;
+ }
+
+ bool unlock_shared_downgrades()
+ {
+ if (upgrade) {
+ upgrade=false;
+ exclusive=true;
+ return true;
+ } else {
+ exclusive_waiting_blocked=false;
+ return false;
+ }
+ }
+
+ void lock_upgrade ()
+ {
+ ++shared_count;
+ upgrade=true;
+ }
+ bool can_lock_upgrade () const
+ {
+ return ! (exclusive || exclusive_waiting_blocked || upgrade);
+ }
+
+ void unlock_upgrade ()
+ {
+ upgrade=false;
+ --shared_count;
+ }
+
+ //private:
+ unsigned shared_count;
+ bool exclusive;
+ bool upgrade;
+ bool exclusive_waiting_blocked;
+ };
+
+
+
+ state_data state;
+ boost::mutex state_change;
+ boost::condition_variable shared_cond;
+ boost::condition_variable exclusive_cond;
+ boost::condition_variable upgrade_cond;
+
+ void release_waiters()
+ {
+ exclusive_cond.notify_one();
+ shared_cond.notify_all();
+ }
+
+ public:
+
+ BOOST_THREAD_NO_COPYABLE(shared_mutex)
+
+ shared_mutex()
+ {
+ }
+
+ ~shared_mutex()
+ {
+ }
+
+ void lock_shared()
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ while(!state.can_lock_shared())
+ {
+ shared_cond.wait(lk);
+ }
+ state.lock_shared();
+ }
+
+ bool try_lock_shared()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+
+ if(!state.can_lock_shared())
+ {
+ return false;
+ }
+ state.lock_shared();
+ return true;
+ }
+
+#if defined BOOST_THREAD_USES_DATETIME
+ bool timed_lock_shared(system_time const& timeout)
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+
+ while(!state.can_lock_shared())
+ {
+ if(!shared_cond.timed_wait(lk,timeout))
+ {
+ return false;
+ }
+ }
+ state.lock_shared();
+ return true;
+ }
+
+ template<typename TimeDuration>
+ bool timed_lock_shared(TimeDuration const & relative_time)
+ {
+ return timed_lock_shared(get_system_time()+relative_time);
+ }
+#endif
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_lock_shared_until(chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool try_lock_shared_until(const chrono::time_point<Clock, Duration>& abs_time)
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+
+ while(!state.can_lock_shared())
+ //while(state.exclusive || state.exclusive_waiting_blocked)
+ {
+ if(cv_status::timeout==shared_cond.wait_until(lk,abs_time))
+ {
+ return false;
+ }
+ }
+ state.lock_shared();
+ return true;
+ }
+#endif
+ void unlock_shared()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_shared();
+ state.unlock_shared();
+ if (! state.more_shared())
+ {
+ if (state.upgrade)
+ {
+ // As there is a thread doing a unlock_upgrade_and_lock that is waiting for ! state.more_shared()
+ // avoid other threads to lock, lock_upgrade or lock_shared, so only this thread is notified.
+ state.upgrade=false;
+ state.exclusive=true;
+ lk.unlock();
+ upgrade_cond.notify_one();
+ }
+ else
+ {
+ state.exclusive_waiting_blocked=false;
+ lk.unlock();
+ }
+ release_waiters();
+ }
+ }
+
+ void lock()
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+
+ while (state.shared_count || state.exclusive)
+ {
+ state.exclusive_waiting_blocked=true;
+ exclusive_cond.wait(lk);
+ }
+ state.exclusive=true;
+ }
+
+#if defined BOOST_THREAD_USES_DATETIME
+ bool timed_lock(system_time const& timeout)
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+
+ while(state.shared_count || state.exclusive)
+ {
+ state.exclusive_waiting_blocked=true;
+ if(!exclusive_cond.timed_wait(lk,timeout))
+ {
+ if(state.shared_count || state.exclusive)
+ {
+ state.exclusive_waiting_blocked=false;
+ release_waiters();
+ return false;
+ }
+ break;
+ }
+ }
+ state.exclusive=true;
+ return true;
+ }
+
+ template<typename TimeDuration>
+ bool timed_lock(TimeDuration const & relative_time)
+ {
+ return timed_lock(get_system_time()+relative_time);
+ }
+#endif
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_lock_until(chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+
+ while(state.shared_count || state.exclusive)
+ {
+ state.exclusive_waiting_blocked=true;
+ if(cv_status::timeout == exclusive_cond.wait_until(lk,abs_time))
+ {
+ if(state.shared_count || state.exclusive)
+ {
+ state.exclusive_waiting_blocked=false;
+ release_waiters();
+ return false;
+ }
+ break;
+ }
+ }
+ state.exclusive=true;
+ return true;
+ }
+#endif
+
+ bool try_lock()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+
+ if(state.shared_count || state.exclusive)
+ {
+ return false;
+ }
+ else
+ {
+ state.exclusive=true;
+ return true;
+ }
+
+ }
+
+ void unlock()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_locked();
+ state.exclusive=false;
+ state.exclusive_waiting_blocked=false;
+ state.assert_free();
+ release_waiters();
+ }
+
+ void lock_upgrade()
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
+ {
+ shared_cond.wait(lk);
+ }
+ state.lock_shared();
+ state.upgrade=true;
+ }
+
+#if defined BOOST_THREAD_USES_DATETIME
+ bool timed_lock_upgrade(system_time const& timeout)
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
+ {
+ if(!shared_cond.timed_wait(lk,timeout))
+ {
+ if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
+ {
+ return false;
+ }
+ break;
+ }
+ }
+ state.lock_shared();
+ state.upgrade=true;
+ return true;
+ }
+
+ template<typename TimeDuration>
+ bool timed_lock_upgrade(TimeDuration const & relative_time)
+ {
+ return timed_lock_upgrade(get_system_time()+relative_time);
+ }
+#endif
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool try_lock_upgrade_for(const chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_lock_upgrade_until(chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool try_lock_upgrade_until(const chrono::time_point<Clock, Duration>& abs_time)
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
+ {
+ if(cv_status::timeout == shared_cond.wait_until(lk,abs_time))
+ {
+ if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
+ {
+ return false;
+ }
+ break;
+ }
+ }
+ state.lock_shared();
+ state.upgrade=true;
+ return true;
+ }
+#endif
+ bool try_lock_upgrade()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
+ {
+ return false;
+ }
+ else
+ {
+ state.lock_shared();
+ state.upgrade=true;
+ state.assert_lock_upgraded();
+ return true;
+ }
+ }
+
+ void unlock_upgrade()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ //state.upgrade=false;
+ state.unlock_upgrade();
+ if(! state.more_shared() )
+ {
+ state.exclusive_waiting_blocked=false;
+ release_waiters();
+ } else {
+ shared_cond.notify_all();
+ }
+ }
+
+ // Upgrade <-> Exclusive
+ void unlock_upgrade_and_lock()
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_upgraded();
+ state.unlock_shared();
+ while (state.more_shared())
+ {
+ upgrade_cond.wait(lk);
+ }
+ state.upgrade=false;
+ state.exclusive=true;
+ state.assert_locked();
+ }
+
+ void unlock_and_lock_upgrade()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_locked();
+ state.exclusive=false;
+ state.upgrade=true;
+ state.lock_shared();
+ state.exclusive_waiting_blocked=false;
+ state.assert_lock_upgraded();
+ release_waiters();
+ }
+
+ bool try_unlock_upgrade_and_lock()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_upgraded();
+ if( !state.exclusive
+ && !state.exclusive_waiting_blocked
+ && state.upgrade
+ && state.shared_count==1)
+ {
+ state.shared_count=0;
+ state.exclusive=true;
+ state.upgrade=false;
+ state.assert_locked();
+ return true;
+ }
+ return false;
+ }
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool
+ try_unlock_upgrade_and_lock_for(
+ const chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_unlock_upgrade_and_lock_until(
+ chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool
+ try_unlock_upgrade_and_lock_until(
+ const chrono::time_point<Clock, Duration>& abs_time)
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_upgraded();
+ if (state.shared_count != 1)
+ {
+ for (;;)
+ {
+ cv_status status = shared_cond.wait_until(lk,abs_time);
+ if (state.shared_count == 1)
+ break;
+ if(status == cv_status::timeout)
+ return false;
+ }
+ }
+ state.upgrade=false;
+ state.exclusive=true;
+ state.exclusive_waiting_blocked=false;
+ state.shared_count=0;
+ return true;
+ }
+#endif
+
+ // Shared <-> Exclusive
+ void unlock_and_lock_shared()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_locked();
+ state.exclusive=false;
+ state.lock_shared();
+ state.exclusive_waiting_blocked=false;
+ release_waiters();
+ }
+
+#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+ bool try_unlock_shared_and_lock()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_shared();
+ if( !state.exclusive
+ && !state.exclusive_waiting_blocked
+ && !state.upgrade
+ && state.shared_count==1)
+ {
+ state.shared_count=0;
+ state.exclusive=true;
+ return true;
+ }
+ return false;
+ }
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool
+ try_unlock_shared_and_lock_for(
+ const chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_unlock_shared_and_lock_until(
+ chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool
+ try_unlock_shared_and_lock_until(
+ const chrono::time_point<Clock, Duration>& abs_time)
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_shared();
+ if (state.shared_count != 1)
+ {
+ for (;;)
+ {
+ cv_status status = shared_cond.wait_until(lk,abs_time);
+ if (state.shared_count == 1)
+ break;
+ if(status == cv_status::timeout)
+ return false;
+ }
+ }
+ state.upgrade=false;
+ state.exclusive=true;
+ state.exclusive_waiting_blocked=false;
+ state.shared_count=0;
+ return true;
+ }
+#endif
+#endif
+
+ // Shared <-> Upgrade
+ void unlock_upgrade_and_lock_shared()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_upgraded();
+ state.upgrade=false;
+ state.exclusive_waiting_blocked=false;
+ release_waiters();
+ }
+
+#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+ bool try_unlock_shared_and_lock_upgrade()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_shared();
+ if( !state.exclusive
+ && !state.exclusive_waiting_blocked
+ && !state.upgrade
+ )
+ {
+ state.upgrade=true;
+ return true;
+ }
+ return false;
+ }
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool
+ try_unlock_shared_and_lock_upgrade_for(
+ const chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_unlock_shared_and_lock_upgrade_until(
+ chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool
+ try_unlock_shared_and_lock_upgrade_until(
+ const chrono::time_point<Clock, Duration>& abs_time)
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_shared();
+ if( state.exclusive
+ || state.exclusive_waiting_blocked
+ || state.upgrade
+ )
+ {
+ for (;;)
+ {
+ cv_status status = exclusive_cond.wait_until(lk,abs_time);
+ if( ! state.exclusive
+ && ! state.exclusive_waiting_blocked
+ && ! state.upgrade
+ )
+ break;
+ if(status == cv_status::timeout)
+ return false;
+ }
+ }
+ state.upgrade=true;
+ return true;
+ }
+#endif
+#endif
+ };
+
+ typedef shared_mutex upgrade_mutex;
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/pthread/shared_mutex_assert.hpp b/src/third_party/boost-1.60.0/boost/thread/pthread/shared_mutex_assert.hpp
new file mode 100644
index 00000000000..186ab7984bd
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/pthread/shared_mutex_assert.hpp
@@ -0,0 +1,724 @@
+#ifndef BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP
+#define BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP
+
+// (C) Copyright 2006-8 Anthony Williams
+// (C) Copyright 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)
+
+#include <boost/assert.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition_variable.hpp>
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+#include <boost/thread/detail/thread_interruption.hpp>
+#endif
+#ifdef BOOST_THREAD_USES_CHRONO
+#include <boost/chrono/system_clocks.hpp>
+#include <boost/chrono/ceil.hpp>
+#endif
+#include <boost/thread/detail/delete.hpp>
+#include <boost/assert.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ class shared_mutex
+ {
+ private:
+ class state_data
+ {
+ public:
+ state_data () :
+ shared_count(0),
+ exclusive(false),
+ upgrade(false),
+ exclusive_waiting_blocked(false)
+ {}
+
+ void assert_free() const
+ {
+ BOOST_ASSERT( ! exclusive );
+ BOOST_ASSERT( ! upgrade );
+ BOOST_ASSERT( shared_count==0 );
+ }
+
+ void assert_locked() const
+ {
+ BOOST_ASSERT( exclusive );
+ BOOST_ASSERT( shared_count==0 );
+ BOOST_ASSERT( ! upgrade );
+ }
+
+ void assert_lock_shared () const
+ {
+ BOOST_ASSERT( ! exclusive );
+ BOOST_ASSERT( shared_count>0 );
+ //BOOST_ASSERT( (! upgrade) || (shared_count>1));
+ // if upgraded there are at least 2 threads sharing the mutex,
+ // except when unlock_upgrade_and_lock has decreased the number of readers but has not taken yet exclusive ownership.
+ }
+
+ void assert_lock_upgraded () const
+ {
+ BOOST_ASSERT( ! exclusive );
+ BOOST_ASSERT( upgrade );
+ BOOST_ASSERT( shared_count>0 );
+ }
+
+ void assert_lock_not_upgraded () const
+ {
+ BOOST_ASSERT( ! upgrade );
+ }
+
+ bool can_lock () const
+ {
+ return ! (shared_count || exclusive);
+ }
+
+ void exclusive_blocked (bool blocked)
+ {
+ exclusive_waiting_blocked = blocked;
+ }
+
+ void lock ()
+ {
+ exclusive = true;
+ }
+
+ void unlock ()
+ {
+ exclusive = false;
+ exclusive_waiting_blocked = false;
+ }
+
+ bool can_lock_shared () const
+ {
+ return ! (exclusive || exclusive_waiting_blocked);
+ }
+
+ bool is_last_shared () const
+ {
+ return !shared_count ;
+ }
+ unsigned get_shared_count () const
+ {
+ return shared_count ;
+ }
+ unsigned lock_shared ()
+ {
+ return ++shared_count;
+ }
+
+
+ void unlock_shared ()
+ {
+ --shared_count;
+ }
+
+ bool unlock_shared_downgrades()
+ {
+ if (upgrade) {
+ upgrade=false;
+ exclusive=true;
+ return true;
+ } else {
+ exclusive_waiting_blocked=false;
+ return false;
+ }
+ }
+
+ void lock_upgrade ()
+ {
+ lock_shared ();
+ upgrade=true;
+ }
+ bool can_lock_upgrade () const
+ {
+ return ! (exclusive || exclusive_waiting_blocked || upgrade);
+ }
+
+ void unlock_upgrade ()
+ {
+ upgrade=false;
+ unlock_shared();
+ }
+
+ //private:
+ unsigned shared_count;
+ bool exclusive;
+ bool upgrade;
+ bool exclusive_waiting_blocked;
+ };
+
+
+
+ state_data state;
+ boost::mutex state_change;
+ boost::condition_variable shared_cond;
+ boost::condition_variable exclusive_cond;
+ boost::condition_variable upgrade_cond;
+
+ void release_waiters()
+ {
+ exclusive_cond.notify_one();
+ shared_cond.notify_all();
+ }
+
+ public:
+ BOOST_THREAD_NO_COPYABLE(shared_mutex)
+
+ shared_mutex()
+ {
+ }
+
+ ~shared_mutex()
+ {
+ }
+
+ void lock_shared()
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+
+ while(!state.can_lock_shared())
+ {
+ shared_cond.wait(lk);
+ }
+ state.lock_shared();
+ }
+
+ bool try_lock_shared()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ if(!state.can_lock_shared())
+ {
+ return false;
+ }
+ else
+ {
+ state.lock_shared();
+ return true;
+ }
+ }
+
+#if defined BOOST_THREAD_USES_DATETIME
+ bool timed_lock_shared(system_time const& timeout)
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+
+ while(!state.can_lock_shared())
+ {
+ if(!shared_cond.timed_wait(lk,timeout))
+ {
+ return false;
+ }
+ }
+ state.lock_shared();
+ return true;
+ }
+
+ template<typename TimeDuration>
+ bool timed_lock_shared(TimeDuration const & relative_time)
+ {
+ return timed_lock_shared(get_system_time()+relative_time);
+ }
+#endif
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_lock_shared_until(chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool try_lock_shared_until(const chrono::time_point<Clock, Duration>& abs_time)
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+
+ while(!state.can_lock_shared())
+ {
+ if(cv_status::timeout==shared_cond.wait_until(lk,abs_time))
+ {
+ return false;
+ }
+ }
+ state.lock_shared();
+ return true;
+ }
+#endif
+ void unlock_shared()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_shared();
+ state.unlock_shared();
+ if (state.get_shared_count () == 0)
+ {
+ if (state.unlock_shared_downgrades())
+ {
+ lk.unlock();
+ upgrade_cond.notify_one();
+ } else {
+ lk.unlock();
+ }
+ release_waiters();
+ }
+ }
+
+ void lock()
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+
+ while(!state.can_lock())
+ {
+ state.exclusive_blocked(true);
+ exclusive_cond.wait(lk);
+ }
+ state.lock();
+ }
+
+#if defined BOOST_THREAD_USES_DATETIME
+ bool timed_lock(system_time const& timeout)
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+
+ while(!state.can_lock())
+ {
+ state.exclusive_blocked(true);
+ if(!exclusive_cond.timed_wait(lk,timeout))
+ {
+ if(!state.can_lock())
+ {
+ state.exclusive_blocked(false);
+ release_waiters();
+ return false;
+ }
+ break;
+ }
+ }
+ state.exclusive=true;
+ //state.lock();
+ return true;
+ }
+
+ template<typename TimeDuration>
+ bool timed_lock(TimeDuration const & relative_time)
+ {
+ return timed_lock(get_system_time()+relative_time);
+ }
+#endif
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_lock_until(chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+
+ while(!state.can_lock())
+ {
+ state.exclusive_blocked(true);
+ if(cv_status::timeout == exclusive_cond.wait_until(lk,abs_time))
+ {
+ if(!state.can_lock())
+ {
+ state.exclusive_blocked(false);
+ release_waiters();
+ return false;
+ }
+ break;
+ }
+ }
+ state.exclusive=true;
+ //state.lock();
+ return true;
+ }
+#endif
+
+ bool try_lock()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+
+ if(!state.can_lock())
+ {
+ return false;
+ }
+ else
+ {
+ state.lock();
+ return true;
+ }
+
+ }
+
+ void unlock()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_locked();
+ state.unlock();
+ state.assert_free();
+ release_waiters();
+ }
+
+ void lock_upgrade()
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ while(!state.can_lock_upgrade())
+ {
+ shared_cond.wait(lk);
+ }
+ state.lock_upgrade();
+ }
+
+#if defined BOOST_THREAD_USES_DATETIME
+ bool timed_lock_upgrade(system_time const& timeout)
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ while(!state.can_lock_upgrade())
+ {
+ if(!shared_cond.timed_wait(lk,timeout))
+ {
+ if(!state.can_lock_upgrade())
+ {
+ return false;
+ }
+ break;
+ }
+ }
+ state.lock_upgrade();
+ return true;
+ }
+
+ template<typename TimeDuration>
+ bool timed_lock_upgrade(TimeDuration const & relative_time)
+ {
+ return timed_lock_upgrade(get_system_time()+relative_time);
+ }
+#endif
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool try_lock_upgrade_for(const chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_lock_upgrade_until(chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool try_lock_upgrade_until(const chrono::time_point<Clock, Duration>& abs_time)
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ while(!state.can_lock_upgrade())
+ {
+ if(cv_status::timeout == shared_cond.wait_until(lk,abs_time))
+ {
+ if(!state.can_lock_upgrade())
+ {
+ return false;
+ }
+ break;
+ }
+ }
+ state.lock_upgrade();
+ return true;
+ }
+#endif
+ bool try_lock_upgrade()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ if(!state.can_lock_upgrade())
+ {
+ return false;
+ }
+ else
+ {
+ state.lock_upgrade();
+ state.assert_lock_upgraded();
+ return true;
+ }
+ }
+
+ void unlock_upgrade()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_upgraded();
+ state.unlock_upgrade();
+ state.assert_lock_not_upgraded ();
+ if(state.get_shared_count () == 0)
+ {
+ state.exclusive_blocked(false);
+ lk.unlock();
+ release_waiters();
+ } else {
+ lk.unlock();
+ shared_cond.notify_all();
+ }
+ }
+
+ // Upgrade <-> Exclusive
+ void unlock_upgrade_and_lock()
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_upgraded();
+ // assert state.get_shared_count() >=1
+ while(
+ //! state.exclusive_waiting_blocked // Fixme: is this needed?
+ //&&
+ state.get_shared_count()!=1)
+ {
+ upgrade_cond.wait(lk);
+ }
+ state.unlock_upgrade();
+ state.lock();
+ state.assert_locked();
+ }
+
+ void unlock_and_lock_upgrade()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_locked();
+ state.unlock();
+ state.lock_upgrade();
+ state.assert_lock_upgraded();
+ release_waiters();
+ }
+
+ bool try_unlock_upgrade_and_lock()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_upgraded();
+ if( //!state.exclusive // this should be removed once the assertion work
+ ! state.exclusive_waiting_blocked // Fixme: why this is needed?
+ //&& state.upgrade // this should be removed once the assertion work
+ && state.get_shared_count()==1)
+ {
+ state.unlock_upgrade();
+ state.lock();
+ state.assert_locked();
+ return true;
+ }
+ return false;
+ }
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool
+ try_unlock_upgrade_and_lock_for(
+ const chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_unlock_upgrade_and_lock_until(
+ chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool
+ try_unlock_upgrade_and_lock_until(
+ const chrono::time_point<Clock, Duration>& abs_time)
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_upgraded();
+ if (//state.exclusive // this should be removed once the assertion work
+ state.exclusive_waiting_blocked // Fixme: is this needed?
+ //|| ! state.upgrade // this should be removed once the assertion work
+ || state.get_shared_count() != 1)
+ {
+ for (;;)
+ {
+ //cv_status status = shared_cond.wait_until(lk,abs_time);
+ cv_status status = upgrade_cond.wait_until(lk,abs_time);
+ if (//!state.exclusive // this should be removed once the assertion work
+ ! state.exclusive_waiting_blocked // Fixme: is this needed?
+ //&& ! state.upgrade // this should be removed once the assertion work
+ && state.get_shared_count() == 1)
+ break;
+ if(status == cv_status::timeout)
+ return false;
+ }
+ }
+ state.unlock_upgrade();
+ state.lock();
+ return true;
+ }
+#endif
+
+ // Shared <-> Exclusive
+ void unlock_and_lock_shared()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_locked();
+ state.unlock();
+ state.lock_shared();
+ release_waiters();
+ }
+
+#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+ bool try_unlock_shared_and_lock()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_shared();
+ if( //!state.exclusive // this should be removed once the assertion work
+ ! state.exclusive_waiting_blocked // Fixme: why this is needed?
+ //&& ! state.upgrade // Fixme: why this is needed if state.get_shared_count()==1?
+ && state.get_shared_count()==1)
+ {
+ state.unlock_shared();
+ state.lock();
+ return true;
+ }
+ return false;
+ }
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool
+ try_unlock_shared_and_lock_for(
+ const chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_unlock_shared_and_lock_until(
+ chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool
+ try_unlock_shared_and_lock_until(
+ const chrono::time_point<Clock, Duration>& abs_time)
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_shared();
+ if ( // !state.exclusive // this should be removed once the assertion work
+ state.exclusive_waiting_blocked // Fixme: is this needed?
+ //|| state.upgrade // Fixme: why this is needed if state.get_shared_count()==1?
+ || state.get_shared_count() != 1)
+ {
+ for (;;)
+ {
+ cv_status status = shared_cond.wait_until(lk,abs_time);
+ if ( //! state.exclusive // this should be removed once the assertion work
+ ! state.exclusive_waiting_blocked // Fixme: is this needed?
+ //&& ! state.upgrade
+ && state.get_shared_count() == 1)
+ break;
+ if(status == cv_status::timeout)
+ return false;
+ }
+ }
+ state.unlock_shared();
+ state.lock();
+ state.upgrade=false; // Is this absolutely needed?
+ state.exclusive_waiting_blocked=false; // Is this absolutely needed?
+ return true;
+ }
+#endif
+#endif
+
+ // Shared <-> Upgrade
+ void unlock_upgrade_and_lock_shared()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_upgraded();
+ //state.unlock_upgrade();
+ //state.lock_shared(); // less efficient
+ state.upgrade=false;
+ state.exclusive_waiting_blocked=false; // Is this absolutely needed?
+ release_waiters();
+ }
+
+#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+ bool try_unlock_shared_and_lock_upgrade()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_shared();
+ if( //! state.exclusive // this should be removed once the assertion work
+ ! state.exclusive_waiting_blocked // Fixme: is this needed?
+ && ! state.upgrade
+ )
+ {
+ state.upgrade=true;
+ return true;
+ }
+ return false;
+ }
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool
+ try_unlock_shared_and_lock_upgrade_for(
+ const chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_unlock_shared_and_lock_upgrade_until(
+ chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool
+ try_unlock_shared_and_lock_upgrade_until(
+ const chrono::time_point<Clock, Duration>& abs_time)
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_shared();
+ if( //state.exclusive // this should be removed once the assertion work
+ state.exclusive_waiting_blocked // Fixme: is this needed?
+ || state.upgrade
+ )
+ {
+ for (;;)
+ {
+ cv_status status = exclusive_cond.wait_until(lk,abs_time);
+ if( //! state.exclusive // this should be removed once the assertion work
+ ! state.exclusive_waiting_blocked // Fixme: is this needed?
+ && ! state.upgrade
+ )
+ break;
+ if(status == cv_status::timeout)
+ return false;
+ }
+ }
+ //state.unlock_shared();
+ //state.lock_upgrade(); // less efficient
+ state.upgrade=true;
+ return true;
+ }
+#endif
+#endif
+ };
+
+ typedef shared_mutex upgrade_mutex;
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/pthread/thread_data.hpp b/src/third_party/boost-1.60.0/boost/thread/pthread/thread_data.hpp
new file mode 100644
index 00000000000..dc8ba0fb1ba
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/pthread/thread_data.hpp
@@ -0,0 +1,292 @@
+#ifndef BOOST_THREAD_PTHREAD_THREAD_DATA_HPP
+#define BOOST_THREAD_PTHREAD_THREAD_DATA_HPP
+// Distributed under the 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 2007 Anthony Williams
+// (C) Copyright 2011-2012 Vicente J. Botet Escriba
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/exceptions.hpp>
+#include <boost/thread/lock_guard.hpp>
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/pthread/condition_variable_fwd.hpp>
+
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <boost/assert.hpp>
+#ifdef BOOST_THREAD_USES_CHRONO
+#include <boost/chrono/system_clocks.hpp>
+#endif
+
+#include <map>
+#include <vector>
+#include <utility>
+
+#if defined(__ANDROID__)
+# ifndef PAGE_SIZE
+# define PAGE_SIZE 4096
+# endif
+#endif
+
+#include <pthread.h>
+#include <unistd.h>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ class thread_attributes {
+ public:
+ thread_attributes() BOOST_NOEXCEPT {
+ int res = pthread_attr_init(&val_);
+ BOOST_VERIFY(!res && "pthread_attr_init failed");
+ }
+ ~thread_attributes() {
+ int res = pthread_attr_destroy(&val_);
+ BOOST_VERIFY(!res && "pthread_attr_destroy failed");
+ }
+ // stack
+ void set_stack_size(std::size_t size) BOOST_NOEXCEPT {
+ if (size==0) return;
+ std::size_t page_size = getpagesize();
+#ifdef PTHREAD_STACK_MIN
+ if (size<PTHREAD_STACK_MIN) size=PTHREAD_STACK_MIN;
+#endif
+ size = ((size+page_size-1)/page_size)*page_size;
+ int res = pthread_attr_setstacksize(&val_, size);
+ BOOST_VERIFY(!res && "pthread_attr_setstacksize failed");
+ }
+
+ std::size_t get_stack_size() const BOOST_NOEXCEPT {
+ std::size_t size;
+ int res = pthread_attr_getstacksize(&val_, &size);
+ BOOST_VERIFY(!res && "pthread_attr_getstacksize failed");
+ return size;
+ }
+#define BOOST_THREAD_DEFINES_THREAD_ATTRIBUTES_NATIVE_HANDLE
+
+ typedef pthread_attr_t native_handle_type;
+ native_handle_type* native_handle() BOOST_NOEXCEPT {
+ return &val_;
+ }
+ const native_handle_type* native_handle() const BOOST_NOEXCEPT {
+ return &val_;
+ }
+
+ private:
+ pthread_attr_t val_;
+ };
+
+ class thread;
+
+ namespace detail
+ {
+ struct shared_state_base;
+ struct tss_cleanup_function;
+ struct thread_exit_callback_node;
+ struct tss_data_node
+ {
+ boost::shared_ptr<boost::detail::tss_cleanup_function> func;
+ void* value;
+
+ tss_data_node(boost::shared_ptr<boost::detail::tss_cleanup_function> func_,
+ void* value_):
+ func(func_),value(value_)
+ {}
+ };
+
+ struct thread_data_base;
+ typedef boost::shared_ptr<thread_data_base> thread_data_ptr;
+
+ struct BOOST_THREAD_DECL thread_data_base:
+ enable_shared_from_this<thread_data_base>
+ {
+ thread_data_ptr self;
+ pthread_t thread_handle;
+ boost::mutex data_mutex;
+ boost::condition_variable done_condition;
+ boost::mutex sleep_mutex;
+ boost::condition_variable sleep_condition;
+ bool done;
+ bool join_started;
+ bool joined;
+ boost::detail::thread_exit_callback_node* thread_exit_callbacks;
+ std::map<void const*,boost::detail::tss_data_node> tss_data;
+
+//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ // These data must be at the end so that the access to the other fields doesn't change
+ // when BOOST_THREAD_PROVIDES_INTERRUPTIONS is defined.
+ // Another option is to have them always
+ pthread_mutex_t* cond_mutex;
+ pthread_cond_t* current_cond;
+//#endif
+ typedef std::vector<std::pair<condition_variable*, mutex*>
+ //, hidden_allocator<std::pair<condition_variable*, mutex*> >
+ > notify_list_t;
+ notify_list_t notify;
+
+ typedef std::vector<shared_ptr<shared_state_base> > async_states_t;
+ async_states_t async_states_;
+
+//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ // These data must be at the end so that the access to the other fields doesn't change
+ // when BOOST_THREAD_PROVIDES_INTERRUPTIONS is defined.
+ // Another option is to have them always
+ bool interrupt_enabled;
+ bool interrupt_requested;
+//#endif
+ thread_data_base():
+ thread_handle(0),
+ done(false),join_started(false),joined(false),
+ thread_exit_callbacks(0),
+//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ cond_mutex(0),
+ current_cond(0),
+//#endif
+ notify(),
+ async_states_()
+//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ , interrupt_enabled(true)
+ , interrupt_requested(false)
+//#endif
+ {}
+ virtual ~thread_data_base();
+
+ typedef pthread_t native_handle_type;
+
+ virtual void run()=0;
+ virtual void notify_all_at_thread_exit(condition_variable* cv, mutex* m)
+ {
+ notify.push_back(std::pair<condition_variable*, mutex*>(cv, m));
+ }
+
+ void make_ready_at_thread_exit(shared_ptr<shared_state_base> as)
+ {
+ async_states_.push_back(as);
+ }
+
+ };
+
+ BOOST_THREAD_DECL thread_data_base* get_current_thread_data();
+
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ class interruption_checker
+ {
+ thread_data_base* const thread_info;
+ pthread_mutex_t* m;
+ bool set;
+
+ void check_for_interruption()
+ {
+#ifndef BOOST_NO_EXCEPTIONS
+ if(thread_info->interrupt_requested)
+ {
+ thread_info->interrupt_requested=false;
+ throw thread_interrupted(); // BOOST_NO_EXCEPTIONS protected
+ }
+#endif
+ }
+
+ void operator=(interruption_checker&);
+ public:
+ explicit interruption_checker(pthread_mutex_t* cond_mutex,pthread_cond_t* cond):
+ thread_info(detail::get_current_thread_data()),m(cond_mutex),
+ set(thread_info && thread_info->interrupt_enabled)
+ {
+ if(set)
+ {
+ lock_guard<mutex> guard(thread_info->data_mutex);
+ check_for_interruption();
+ thread_info->cond_mutex=cond_mutex;
+ thread_info->current_cond=cond;
+ BOOST_VERIFY(!pthread_mutex_lock(m));
+ }
+ else
+ {
+ BOOST_VERIFY(!pthread_mutex_lock(m));
+ }
+ }
+ ~interruption_checker()
+ {
+ if(set)
+ {
+ BOOST_VERIFY(!pthread_mutex_unlock(m));
+ lock_guard<mutex> guard(thread_info->data_mutex);
+ thread_info->cond_mutex=NULL;
+ thread_info->current_cond=NULL;
+ }
+ else
+ {
+ BOOST_VERIFY(!pthread_mutex_unlock(m));
+ }
+ }
+ };
+#endif
+ }
+
+ namespace this_thread
+ {
+ namespace hiden
+ {
+ void BOOST_THREAD_DECL sleep_for(const timespec& ts);
+ void BOOST_THREAD_DECL sleep_until(const timespec& ts);
+ }
+
+#ifdef BOOST_THREAD_USES_CHRONO
+#ifdef BOOST_THREAD_SLEEP_FOR_IS_STEADY
+
+ inline
+ void BOOST_SYMBOL_VISIBLE sleep_for(const chrono::nanoseconds& ns)
+ {
+ return boost::this_thread::hiden::sleep_for(boost::detail::to_timespec(ns));
+ }
+#endif
+#endif // BOOST_THREAD_USES_CHRONO
+
+ namespace no_interruption_point
+ {
+ namespace hiden
+ {
+ void BOOST_THREAD_DECL sleep_for(const timespec& ts);
+ void BOOST_THREAD_DECL sleep_until(const timespec& ts);
+ }
+
+ #ifdef BOOST_THREAD_USES_CHRONO
+ #ifdef BOOST_THREAD_SLEEP_FOR_IS_STEADY
+
+ inline
+ void BOOST_SYMBOL_VISIBLE sleep_for(const chrono::nanoseconds& ns)
+ {
+ return boost::this_thread::no_interruption_point::hiden::sleep_for(boost::detail::to_timespec(ns));
+ }
+ #endif
+ #endif // BOOST_THREAD_USES_CHRONO
+
+ } // no_interruption_point
+
+ void BOOST_THREAD_DECL yield() BOOST_NOEXCEPT;
+
+#if defined BOOST_THREAD_USES_DATETIME
+#ifdef __DECXXX
+ /// Workaround of DECCXX issue of incorrect template substitution
+ template<>
+#endif
+ inline void sleep(system_time const& abs_time)
+ {
+ return boost::this_thread::hiden::sleep_until(boost::detail::to_timespec(abs_time));
+ }
+
+ template<typename TimeDuration>
+ inline BOOST_SYMBOL_VISIBLE void sleep(TimeDuration const& rel_time)
+ {
+ this_thread::sleep(get_system_time()+rel_time);
+ }
+#endif // BOOST_THREAD_USES_DATETIME
+ } // this_thread
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/pthread/thread_heap_alloc.hpp b/src/third_party/boost-1.60.0/boost/thread/pthread/thread_heap_alloc.hpp
new file mode 100644
index 00000000000..7828318f05f
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/pthread/thread_heap_alloc.hpp
@@ -0,0 +1,242 @@
+// Distributed under the 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 2008 Anthony Williams
+#ifndef THREAD_HEAP_ALLOC_PTHREAD_HPP
+#define THREAD_HEAP_ALLOC_PTHREAD_HPP
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ namespace detail
+ {
+ template<typename T>
+ inline T* heap_new()
+ {
+ return new T();
+ }
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ template<typename T,typename A1>
+ inline T* heap_new(A1&& a1)
+ {
+ return new T(static_cast<A1&&>(a1));
+ }
+ template<typename T,typename A1,typename A2>
+ inline T* heap_new(A1&& a1,A2&& a2)
+ {
+ return new T(static_cast<A1&&>(a1),static_cast<A2&&>(a2));
+ }
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1&& a1,A2&& a2,A3&& a3)
+ {
+ return new T(static_cast<A1&&>(a1),static_cast<A2&&>(a2),
+ static_cast<A3&&>(a3));
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1&& a1,A2&& a2,A3&& a3,A4&& a4)
+ {
+ return new T(static_cast<A1&&>(a1),static_cast<A2&&>(a2),
+ static_cast<A3&&>(a3),static_cast<A4&&>(a4));
+ }
+#else
+ template<typename T,typename A1>
+ inline T* heap_new_impl(A1 a1)
+ {
+ return new T(a1);
+ }
+ template<typename T,typename A1,typename A2>
+ inline T* heap_new_impl(A1 a1,A2 a2)
+ {
+ return new T(a1,a2);
+ }
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new_impl(A1 a1,A2 a2,A3 a3)
+ {
+ return new T(a1,a2,a3);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new_impl(A1 a1,A2 a2,A3 a3,A4 a4)
+ {
+ return new T(a1,a2,a3,a4);
+ }
+
+ template<typename T,typename A1>
+ inline T* heap_new(A1 const& a1)
+ {
+ return heap_new_impl<T,A1 const&>(a1);
+ }
+ template<typename T,typename A1>
+ inline T* heap_new(A1& a1)
+ {
+ return heap_new_impl<T,A1&>(a1);
+ }
+
+ template<typename T,typename A1,typename A2>
+ inline T* heap_new(A1 const& a1,A2 const& a2)
+ {
+ return heap_new_impl<T,A1 const&,A2 const&>(a1,a2);
+ }
+ template<typename T,typename A1,typename A2>
+ inline T* heap_new(A1& a1,A2 const& a2)
+ {
+ return heap_new_impl<T,A1&,A2 const&>(a1,a2);
+ }
+ template<typename T,typename A1,typename A2>
+ inline T* heap_new(A1 const& a1,A2& a2)
+ {
+ return heap_new_impl<T,A1 const&,A2&>(a1,a2);
+ }
+ template<typename T,typename A1,typename A2>
+ inline T* heap_new(A1& a1,A2& a2)
+ {
+ return heap_new_impl<T,A1&,A2&>(a1,a2);
+ }
+
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1 const& a1,A2 const& a2,A3 const& a3)
+ {
+ return heap_new_impl<T,A1 const&,A2 const&,A3 const&>(a1,a2,a3);
+ }
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1& a1,A2 const& a2,A3 const& a3)
+ {
+ return heap_new_impl<T,A1&,A2 const&,A3 const&>(a1,a2,a3);
+ }
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1 const& a1,A2& a2,A3 const& a3)
+ {
+ return heap_new_impl<T,A1 const&,A2&,A3 const&>(a1,a2,a3);
+ }
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1& a1,A2& a2,A3 const& a3)
+ {
+ return heap_new_impl<T,A1&,A2&,A3 const&>(a1,a2,a3);
+ }
+
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1 const& a1,A2 const& a2,A3& a3)
+ {
+ return heap_new_impl<T,A1 const&,A2 const&,A3&>(a1,a2,a3);
+ }
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1& a1,A2 const& a2,A3& a3)
+ {
+ return heap_new_impl<T,A1&,A2 const&,A3&>(a1,a2,a3);
+ }
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1 const& a1,A2& a2,A3& a3)
+ {
+ return heap_new_impl<T,A1 const&,A2&,A3&>(a1,a2,a3);
+ }
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1& a1,A2& a2,A3& a3)
+ {
+ return heap_new_impl<T,A1&,A2&,A3&>(a1,a2,a3);
+ }
+
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2 const& a2,A3 const& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2 const&,A3 const&,A4 const&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2 const& a2,A3 const& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1&,A2 const&,A3 const&,A4 const&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2& a2,A3 const& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2&,A3 const&,A4 const&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2& a2,A3 const& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1&,A2&,A3 const&,A4 const&>(a1,a2,a3,a4);
+ }
+
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2 const& a2,A3& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2 const&,A3&,A4 const&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2 const& a2,A3& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1&,A2 const&,A3&,A4 const&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2& a2,A3& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2&,A3&,A4 const&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2& a2,A3& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1&,A2&,A3&,A4 const&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2 const& a2,A3 const& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2 const&,A3 const&,A4&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2 const& a2,A3 const& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1&,A2 const&,A3 const&,A4&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2& a2,A3 const& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2&,A3 const&,A4&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2& a2,A3 const& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1&,A2&,A3 const&,A4&>(a1,a2,a3,a4);
+ }
+
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2 const& a2,A3& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2 const&,A3&,A4&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2 const& a2,A3& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1&,A2 const&,A3&,A4&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2& a2,A3& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2&,A3&,A4&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2& a2,A3& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1&,A2&,A3&,A4&>(a1,a2,a3,a4);
+ }
+
+#endif
+ template<typename T>
+ inline void heap_delete(T* data)
+ {
+ delete data;
+ }
+
+ template<typename T>
+ struct do_heap_delete
+ {
+ void operator()(T* data) const
+ {
+ detail::heap_delete(data);
+ }
+ };
+ }
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/pthread/timespec.hpp b/src/third_party/boost-1.60.0/boost/thread/pthread/timespec.hpp
new file mode 100644
index 00000000000..82f50f6ca74
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/pthread/timespec.hpp
@@ -0,0 +1,120 @@
+#ifndef BOOST_THREAD_PTHREAD_TIMESPEC_HPP
+#define BOOST_THREAD_PTHREAD_TIMESPEC_HPP
+// (C) Copyright 2007-8 Anthony Williams
+// (C) Copyright 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)
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/thread_time.hpp>
+#if defined BOOST_THREAD_USES_DATETIME
+#include <boost/date_time/posix_time/conversion.hpp>
+#endif
+#include <pthread.h>
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+#ifdef BOOST_THREAD_USES_CHRONO
+#include <boost/chrono/duration.hpp>
+#endif
+
+#if defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
+# define BOOST_THREAD_TIMESPEC_MAC_API
+#include <sys/time.h> //for gettimeofday and timeval
+#else
+#include <time.h> // for clock_gettime
+#endif
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ namespace detail
+ {
+#if defined BOOST_THREAD_USES_DATETIME
+ inline struct timespec to_timespec(boost::system_time const& abs_time)
+ {
+ struct timespec timeout = { 0,0};
+ boost::posix_time::time_duration const time_since_epoch=abs_time-boost::posix_time::from_time_t(0);
+
+ timeout.tv_sec=time_since_epoch.total_seconds();
+ timeout.tv_nsec=(long)(time_since_epoch.fractional_seconds()*(1000000000l/time_since_epoch.ticks_per_second()));
+ return timeout;
+ }
+#endif
+#if defined BOOST_THREAD_USES_CHRONO
+ inline timespec to_timespec(chrono::nanoseconds const& ns)
+ {
+ struct timespec ts;
+ ts.tv_sec = static_cast<long>(chrono::duration_cast<chrono::seconds>(ns).count());
+ ts.tv_nsec = static_cast<long>((ns - chrono::duration_cast<chrono::seconds>(ns)).count());
+ return ts;
+ }
+
+#endif
+
+ inline timespec to_timespec(boost::intmax_t const& ns)
+ {
+ boost::intmax_t s = ns / 1000000000l;
+ struct timespec ts;
+ ts.tv_sec = static_cast<long> (s);
+ ts.tv_nsec = static_cast<long> (ns - s * 1000000000l);
+ return ts;
+ }
+ inline boost::intmax_t to_nanoseconds_int_max(timespec const& ts)
+ {
+ return static_cast<boost::intmax_t>(ts.tv_sec) * 1000000000l + ts.tv_nsec;
+ }
+ inline bool timespec_ge_zero(timespec const& ts)
+ {
+ return (ts.tv_sec >= 0) || (ts.tv_nsec >= 0);
+ }
+ inline timespec timespec_now()
+ {
+ timespec ts;
+
+#if defined(BOOST_THREAD_TIMESPEC_MAC_API)
+ timeval tv;
+ ::gettimeofday(&tv, 0);
+ ts.tv_sec = tv.tv_sec;
+ ts.tv_nsec = tv.tv_usec * 1000;
+#else
+ if ( ::clock_gettime( CLOCK_REALTIME, &ts ) )
+ {
+ BOOST_ASSERT(0 && "Boost::Thread - Internal Error");
+ }
+#endif
+ return ts;
+ }
+ inline timespec timespec_zero()
+ {
+ timespec ts;
+ ts.tv_sec = 0;
+ ts.tv_nsec = 0;
+ return ts;
+ }
+ inline timespec timespec_plus(timespec const& lhs, timespec const& rhs)
+ {
+ return to_timespec(to_nanoseconds_int_max(lhs) + to_nanoseconds_int_max(rhs));
+ }
+ inline timespec timespec_minus(timespec const& lhs, timespec const& rhs)
+ {
+ return to_timespec(to_nanoseconds_int_max(lhs) - to_nanoseconds_int_max(rhs));
+ }
+ inline bool timespec_gt(timespec const& lhs, timespec const& rhs)
+ {
+ return to_nanoseconds_int_max(lhs) > to_nanoseconds_int_max(rhs);
+ }
+ inline bool timespec_ge(timespec const& lhs, timespec const& rhs)
+ {
+ return to_nanoseconds_int_max(lhs) >= to_nanoseconds_int_max(rhs);
+ }
+
+ }
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/recursive_mutex.hpp b/src/third_party/boost-1.60.0/boost/thread/recursive_mutex.hpp
new file mode 100644
index 00000000000..e716a190ffb
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/recursive_mutex.hpp
@@ -0,0 +1,64 @@
+#ifndef BOOST_THREAD_RECURSIVE_MUTEX_HPP
+#define BOOST_THREAD_RECURSIVE_MUTEX_HPP
+
+// recursive_mutex.hpp
+//
+// (C) Copyright 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/detail/platform.hpp>
+#if defined(BOOST_THREAD_PLATFORM_WIN32)
+#include <boost/thread/win32/recursive_mutex.hpp>
+#elif defined(BOOST_THREAD_PLATFORM_PTHREAD)
+#include <boost/thread/pthread/recursive_mutex.hpp>
+#else
+#error "Boost threads unavailable on this platform"
+#endif
+
+#include <boost/thread/lockable_traits.hpp>
+
+namespace boost
+{
+ namespace sync
+ {
+
+#ifdef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
+ template<>
+ struct is_basic_lockable<recursive_mutex>
+ {
+ BOOST_STATIC_CONSTANT(bool, value = true);
+ };
+ template<>
+ struct is_lockable<recursive_mutex>
+ {
+ BOOST_STATIC_CONSTANT(bool, value = true);
+ };
+ template<>
+ struct is_basic_lockable<recursive_timed_mutex>
+ {
+ BOOST_STATIC_CONSTANT(bool, value = true);
+ };
+ template<>
+ struct is_lockable<recursive_timed_mutex>
+ {
+ BOOST_STATIC_CONSTANT(bool, value = true);
+ };
+#endif
+
+ template<>
+ struct is_recursive_mutex_sur_parolle<recursive_mutex>
+ {
+ BOOST_STATIC_CONSTANT(bool, value = true);
+ };
+ template<>
+ struct is_recursive_mutex_sur_parolle<recursive_timed_mutex>
+ {
+ BOOST_STATIC_CONSTANT(bool, value = true);
+ };
+
+ }
+}
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/reverse_lock.hpp b/src/third_party/boost-1.60.0/boost/thread/reverse_lock.hpp
new file mode 100644
index 00000000000..479c314bdbe
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/reverse_lock.hpp
@@ -0,0 +1,59 @@
+// Distributed under the 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 2012 Vicente J. Botet Escriba
+
+#ifndef BOOST_THREAD_REVERSE_LOCK_HPP
+#define BOOST_THREAD_REVERSE_LOCK_HPP
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/lockable_traits.hpp>
+#include <boost/thread/lock_options.hpp>
+#include <boost/thread/detail/delete.hpp>
+
+namespace boost
+{
+
+ template<typename Lock>
+ class reverse_lock
+ {
+ public:
+ typedef typename Lock::mutex_type mutex_type;
+ BOOST_THREAD_NO_COPYABLE(reverse_lock)
+
+ explicit reverse_lock(Lock& m_)
+ : m(m_), mtx(0)
+ {
+ if (m.owns_lock())
+ {
+ m.unlock();
+ }
+ mtx=m.release();
+ }
+ ~reverse_lock()
+ {
+ if (mtx) {
+ mtx->lock();
+ m = BOOST_THREAD_MAKE_RV_REF(Lock(*mtx, adopt_lock));
+ }
+ }
+
+ private:
+ Lock& m;
+ mutex_type* mtx;
+ };
+
+
+#ifdef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
+ template<typename T>
+ struct is_mutex_type<reverse_lock<T> >
+ {
+ BOOST_STATIC_CONSTANT(bool, value = true);
+ };
+
+#endif
+
+
+}
+
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/scoped_thread.hpp b/src/third_party/boost-1.60.0/boost/thread/scoped_thread.hpp
new file mode 100644
index 00000000000..ae0d1efc53c
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/scoped_thread.hpp
@@ -0,0 +1,289 @@
+// Distributed under the 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 2009-2012 Anthony Williams
+// (C) Copyright 2012 Vicente J. Botet Escriba
+
+// Based on the Anthony's idea of scoped_thread in CCiA
+
+#ifndef BOOST_THREAD_SCOPED_THREAD_HPP
+#define BOOST_THREAD_SCOPED_THREAD_HPP
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/detail/delete.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/thread_functors.hpp>
+#include <boost/thread/thread_only.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+
+ /**
+ * RAI @c thread wrapper adding a specific destroyer allowing to master what can be done at destruction time.
+ *
+ * CallableThread: A callable void(thread&) .
+ * The default is a join_if_joinable.
+ *
+ * thread std/boost::thread destructor terminates the program if the thread is not joinable.
+ * Having a wrapper that can join the thread before destroying it seems a natural need.
+ *
+ * Example:
+ *
+ * boost::strict_scoped_thread<> t((boost::thread(F)));
+ *
+ */
+ template <class CallableThread = join_if_joinable>
+ class strict_scoped_thread
+ {
+ thread t_;
+ struct dummy;
+ public:
+
+ BOOST_THREAD_NO_COPYABLE( strict_scoped_thread) /// non copyable
+
+ /*
+ *
+ */
+#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template <class F, class ...Args, typename = typename disable_if<is_same<typename decay<F>::type, thread>, void* >::type>
+ explicit strict_scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(Args)... args) :
+ t_(boost::forward<F>(f), boost::forward<Args>(args)...) {}
+#else
+ template <class F>
+ explicit strict_scoped_thread(BOOST_THREAD_FWD_REF(F) f,
+ typename disable_if<is_same<typename decay<F>::type, thread>, void* >::type=0) :
+ t_(boost::forward<F>(f)) {}
+ template <class F, class A1>
+ strict_scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1) :
+ t_(boost::forward<F>(f), boost::forward<A1>(a1)) {}
+ template <class F, class A1, class A2>
+ strict_scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1, BOOST_THREAD_FWD_REF(A2) a2) :
+ t_(boost::forward<F>(f), boost::forward<A1>(a1), boost::forward<A2>(a2)) {}
+ template <class F, class A1, class A2, class A3>
+ strict_scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1, BOOST_THREAD_FWD_REF(A2) a2, BOOST_THREAD_FWD_REF(A3) a3) :
+ t_(boost::forward<F>(f), boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3)) {}
+#endif
+
+ /**
+ * Constructor from the thread to own.
+ *
+ * @param t: the thread to own.
+ *
+ * Effects: move the thread to own @c t.
+ */
+ explicit strict_scoped_thread(BOOST_THREAD_RV_REF(thread) t) BOOST_NOEXCEPT :
+ t_(boost::move(t))
+ {
+ }
+
+ /**
+ * Destructor
+ * Effects: Call the CallableThread functor before destroying the owned thread.
+ * Remark: The CallableThread should not throw when joining the thread as the scoped variable is on a scope outside the thread function.
+ */
+ ~strict_scoped_thread()
+ {
+ CallableThread on_destructor;
+
+ on_destructor(t_);
+ }
+
+ };
+
+ /**
+ * RAI @c thread wrapper adding a specific destroyer allowing to master what can be done at destruction time.
+ *
+ * CallableThread: A callable void(thread&) .
+ * The default is join_if_joinable.
+ *
+ * thread std::thread destructor terminates the program if the thread is not joinable.
+ * Having a wrapper that can join the thread before destroying it seems a natural need.
+ *
+ * Remark: @c scoped_thread is not a @c thread as @c thread is not designed to be derived from as a polymorphic type.
+ * Anyway @c scoped_thread can be used in most of the contexts a @c thread could be used as it has the
+ * same non-deprecated interface with the exception of the construction.
+ *
+ * Example:
+ *
+ * boost::scoped_thread<> t((boost::thread(F)));
+ * t.interrupt();
+ *
+ */
+ template <class CallableThread = join_if_joinable>
+ class scoped_thread
+ {
+ thread t_;
+ struct dummy;
+ public:
+
+ typedef thread::id id;
+
+ BOOST_THREAD_MOVABLE_ONLY( scoped_thread) /// Movable only
+
+ /**
+ * Default Constructor.
+ *
+ * Effects: wraps a not-a-thread.
+ */
+ scoped_thread() BOOST_NOEXCEPT:
+ t_()
+ {
+ }
+
+ /**
+ *
+ */
+
+#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template <class F, class ...Args, typename = typename disable_if<is_same<typename decay<F>::type, thread>, void* >::type>
+ explicit scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(Args)... args) :
+ t_(boost::forward<F>(f), boost::forward<Args>(args)...) {}
+#else
+ template <class F>
+ explicit scoped_thread(BOOST_THREAD_FWD_REF(F) f,
+ typename disable_if<is_same<typename decay<F>::type, thread>, void* >::type=0) :
+ t_(boost::forward<F>(f)) {}
+ template <class F, class A1>
+ scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1) :
+ t_(boost::forward<F>(f), boost::forward<A1>(a1)) {}
+ template <class F, class A1, class A2>
+ scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1, BOOST_THREAD_FWD_REF(A2) a2) :
+ t_(boost::forward<F>(f), boost::forward<A1>(a1), boost::forward<A2>(a2)) {}
+ template <class F, class A1, class A2, class A3>
+ scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1, BOOST_THREAD_FWD_REF(A2) a2, BOOST_THREAD_FWD_REF(A3) a3) :
+ t_(boost::forward<F>(f), boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3)) {}
+
+#endif
+ /**
+ * Constructor from the thread to own.
+ *
+ * @param t: the thread to own.
+ *
+ * Effects: move the thread to own @c t.
+ */
+ explicit scoped_thread(BOOST_THREAD_RV_REF(thread) t) BOOST_NOEXCEPT :
+ t_(boost::move(t))
+ {
+ }
+
+// explicit operator thread()
+// {
+// return boost::move(t_);
+// }
+
+ /**
+ * Move constructor.
+ */
+ scoped_thread(BOOST_RV_REF(scoped_thread) x) BOOST_NOEXCEPT :
+ t_(boost::move(BOOST_THREAD_RV(x).t_))
+ {}
+
+ /**
+ * Destructor
+ *
+ * Effects: Call the CallableThread functor before destroying the owned thread.
+ */
+ ~scoped_thread()
+ {
+ CallableThread on_destructor;
+
+ on_destructor(t_);
+ }
+
+ /**
+ * Move assignment.
+ */
+ scoped_thread& operator=(BOOST_RV_REF(scoped_thread) x)
+ {
+ t_ = boost::move(BOOST_THREAD_RV(x).t_);
+ return *this;
+ }
+
+ /**
+ *
+ */
+ void swap(scoped_thread& x) BOOST_NOEXCEPT
+ {
+ t_.swap(x.t_);
+ }
+
+ // forwarded thread functions
+ inline thread::id get_id() const BOOST_NOEXCEPT
+ {
+ return t_.get_id();
+ }
+
+ void detach()
+ {
+ t_.detach();
+ }
+
+ void join()
+ {
+ t_.join();
+ }
+
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool try_join_for(const chrono::duration<Rep, Period>& rel_time)
+ {
+ return t_.try_join_for(rel_time);
+ }
+
+ template <class Clock, class Duration>
+ bool try_join_until(const chrono::time_point<Clock, Duration>& abs_time)
+ {
+ return t_.try_join_until(abs_time);
+ }
+#endif
+
+ thread::native_handle_type native_handle()BOOST_NOEXCEPT
+ {
+ return t_.native_handle();
+ }
+
+ bool joinable() const BOOST_NOEXCEPT
+ {
+ return t_.joinable();
+ }
+
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ void interrupt()
+ {
+ t_.interrupt();
+ }
+
+ bool interruption_requested() const BOOST_NOEXCEPT
+ {
+ return t_.interruption_requested();
+ }
+#endif
+
+ static unsigned hardware_concurrency() BOOST_NOEXCEPT
+ {
+ return thread::hardware_concurrency();
+ }
+
+#ifdef BOOST_THREAD_PROVIDES_PHYSICAL_CONCURRENCY
+ static unsigned physical_concurrency() BOOST_NOEXCEPT
+ {
+ return thread::physical_concurrency();
+ }
+#endif
+ };
+
+ /**
+ * Effects: swaps the contents of two scoped threads.
+ */
+ template <class Destroyer>
+ void swap(scoped_thread<Destroyer>& lhs, scoped_thread<Destroyer>& rhs)
+BOOST_NOEXCEPT {
+ return lhs.swap(rhs);
+}
+
+}
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/shared_lock_guard.hpp b/src/third_party/boost-1.60.0/boost/thread/shared_lock_guard.hpp
new file mode 100644
index 00000000000..97a6397c1e6
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/shared_lock_guard.hpp
@@ -0,0 +1,53 @@
+// Distributed under the 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 2012 Vicente J. Botet Escriba
+
+#ifndef BOOST_THREAD_SHARED_LOCK_GUARD_HPP
+#define BOOST_THREAD_SHARED_LOCK_GUARD_HPP
+#include <boost/thread/detail/config.hpp>
+//#include <boost/thread/locks.hpp>
+#include <boost/thread/lock_options.hpp>
+#include <boost/thread/detail/delete.hpp>
+
+namespace boost
+{
+
+ template<typename SharedMutex>
+ class shared_lock_guard
+ {
+ private:
+ SharedMutex& m;
+
+ public:
+ typedef SharedMutex mutex_type;
+ BOOST_THREAD_NO_COPYABLE(shared_lock_guard)
+ explicit shared_lock_guard(SharedMutex& m_):
+ m(m_)
+ {
+ m.lock_shared();
+ }
+ shared_lock_guard(SharedMutex& m_,adopt_lock_t):
+ m(m_)
+ {}
+ ~shared_lock_guard()
+ {
+ m.unlock_shared();
+ }
+ };
+
+#ifdef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
+
+ template<typename T>
+ struct is_mutex_type<shared_lock_guard<T> >
+ {
+ BOOST_STATIC_CONSTANT(bool, value = true);
+ };
+
+
+#endif
+
+
+}
+
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/shared_mutex.hpp b/src/third_party/boost-1.60.0/boost/thread/shared_mutex.hpp
new file mode 100644
index 00000000000..ce5d6d1bfbf
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/shared_mutex.hpp
@@ -0,0 +1,50 @@
+#ifndef BOOST_THREAD_SHARED_MUTEX_HPP
+#define BOOST_THREAD_SHARED_MUTEX_HPP
+
+// shared_mutex.hpp
+//
+// (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)
+
+#include <boost/thread/detail/config.hpp>
+#if defined(BOOST_THREAD_PLATFORM_WIN32)
+#if defined(BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN)
+#include <boost/thread/pthread/shared_mutex.hpp>
+#else
+#include <boost/thread/win32/shared_mutex.hpp>
+#endif
+#elif defined(BOOST_THREAD_PLATFORM_PTHREAD)
+//#include <boost/thread/v2/shared_mutex.hpp>
+#include <boost/thread/pthread/shared_mutex.hpp>
+#else
+#error "Boost threads unavailable on this platform"
+#endif
+
+#include <boost/thread/lockable_traits.hpp>
+
+namespace boost
+{
+ typedef shared_mutex shared_timed_mutex;
+ namespace sync
+ {
+#ifdef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
+ template<>
+ struct is_basic_lockable<shared_mutex>
+ {
+ BOOST_STATIC_CONSTANT(bool, value = true);
+ };
+ template<>
+ struct is_lockable<shared_mutex>
+ {
+ BOOST_STATIC_CONSTANT(bool, value = true);
+ };
+#endif
+
+ }
+}
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/strict_lock.hpp b/src/third_party/boost-1.60.0/boost/thread/strict_lock.hpp
new file mode 100644
index 00000000000..93b7b1e71cd
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/strict_lock.hpp
@@ -0,0 +1,235 @@
+// Distributed under the 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 2008-2009,2012 Vicente J. Botet Escriba
+
+#ifndef BOOST_THREAD_STRICT_LOCK_HPP
+#define BOOST_THREAD_STRICT_LOCK_HPP
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/detail/delete.hpp>
+#include <boost/thread/detail/lockable_wrapper.hpp>
+#include <boost/thread/lock_options.hpp>
+#include <boost/thread/lock_traits.hpp>
+#include <boost/thread/lockable_traits.hpp>
+#include <boost/thread/lockable_concepts.hpp>
+#include <boost/thread/lock_concepts.hpp>
+#include <boost/thread/exceptions.hpp>
+#include <boost/throw_exception.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+
+
+ //[strict_lock
+ template <typename Lockable>
+ class strict_lock
+ {
+
+ BOOST_CONCEPT_ASSERT(( BasicLockable<Lockable> ));
+ public:
+ typedef Lockable mutex_type;
+
+ // construct/copy/destroy:
+
+ BOOST_THREAD_NO_COPYABLE( strict_lock)
+
+ /**
+ * Constructor from a mutex reference.
+ *
+ * @param mtx the mutex to lock.
+ *
+ * __Effects: Stores a reference to the mutex to lock and locks it.
+ * __Throws: Any exception BasicMutex::lock() can throw.
+ */
+ explicit strict_lock(mutex_type& mtx) :
+ mtx_(mtx)
+ {
+ mtx.lock();
+ } /*< locks on construction >*/
+
+
+#if ! defined BOOST_THREAD_NO_CXX11_HDR_INITIALIZER_LIST
+ strict_lock(std::initializer_list<thread_detail::lockable_wrapper<Lockable> > l_) :
+ mtx_(*(const_cast<thread_detail::lockable_wrapper<Lockable>*>(l_.begin())->m))
+ {
+ mtx_.lock();
+ }
+#endif
+
+ /**
+ * Destructor
+ *
+ * __Effects: unlocks the stored mutex.
+ *
+ * __Throws
+ */
+ ~strict_lock()
+ {
+ mtx_.unlock();
+ } /*< unlocks on destruction >*/
+
+
+ // observers
+
+ /**
+ * @return the owned mutex.
+ */
+ mutex_type* mutex() const BOOST_NOEXCEPT
+ {
+ return &mtx_;
+ }
+
+ /**
+ * @return whether this lock is locking a mutex.
+ */
+ bool owns_lock() const BOOST_NOEXCEPT
+ {
+ return true;
+ }
+
+ /**
+ * @return whether this lock is locking that mutex.
+ */
+ bool owns_lock(const mutex_type* l) const BOOST_NOEXCEPT
+ {
+ return l == mutex();
+ } /*< strict locks specific function >*/
+
+ //BOOST_ADRESS_OF_DELETE(strict_lock) /*< disable aliasing >*/
+ //BOOST_HEAP_ALLOCATION_DELETE(strict_lock) /*< disable heap allocation >*/
+
+ /*< no possibility to unlock >*/
+
+ private:
+ mutex_type& mtx_;
+ };
+ //]
+ template <typename Lockable>
+ struct is_strict_lock_sur_parole<strict_lock<Lockable> > : true_type
+ {
+ };
+
+ /**
+ * A nested strict lock is a scoped lock guard ensuring the mutex is locked on its
+ * scope, by taking ownership of an nesting lock, locking the mutex on construction if not already locked
+ * and restoring the ownership to the nesting lock on destruction.
+ */
+ //[nested_strict_lock
+ template <typename Lock>
+ class nested_strict_lock
+ {
+ BOOST_CONCEPT_ASSERT(( BasicLock<Lock> )); /*< The Lock must be a movable lock >*/
+ public:
+ typedef typename Lock::mutex_type mutex_type; /*< Name the lockable type locked by Lock >*/
+
+ BOOST_THREAD_NO_COPYABLE( nested_strict_lock)
+
+ /**
+ * Constructor from a nesting @c Lock.
+ *
+ * @param lk the nesting lock
+ *
+ * __Requires: <c>lk.mutex() != null_ptr</c>
+ * __Effects: Stores the reference to the lock parameter and takes ownership on it.
+ * If the lock doesn't owns the mutex @c mtx lock it.
+ * __Postconditions: @c owns_lock(lk.mutex())
+ * __StrongException
+ * __Throws:
+ *
+ * - lock_error when BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is defined and lk.mutex() == null_ptr
+ *
+ * - Any exception that @c lk.lock() can throw.
+ *
+ */
+ explicit nested_strict_lock(Lock& lk) :
+ lk_(lk) /*< Store reference to lk >*/
+ {
+ /*< Define BOOST_THREAD_DONT_CHECK_PRECONDITIONS if you don't want to check lk ownership >*/
+ BOOST_THREAD_ASSERT_PRECONDITION( lk.mutex() != 0,
+ lock_error()
+ );
+ if (!lk.owns_lock()) lk.lock(); /*< ensures it is locked >*/
+ tmp_lk_ = move(lk); /*< Move ownership to temporary lk >*/
+ }
+
+#if ! defined BOOST_THREAD_NO_CXX11_HDR_INITIALIZER_LIST
+ nested_strict_lock(std::initializer_list<thread_detail::lockable_wrapper<Lock> > l_) :
+ lk_(*(const_cast<thread_detail::lockable_wrapper<Lock>*>(l_.begin())->m))
+ {
+ /*< Define BOOST_THREAD_DONT_CHECK_PRECONDITIONS if you don't want to check lk ownership >*/
+ BOOST_THREAD_ASSERT_PRECONDITION( lk_.mutex() != 0,
+ lock_error()
+ );
+ if (!lk_.owns_lock()) lk_.lock(); /*< ensures it is locked >*/
+ tmp_lk_ = move(lk_); /*< Move ownership to temporary lk >*/
+ }
+#endif
+
+ /**
+ * Destructor
+ *
+ * __Effects: Restores ownership to the nesting lock.
+ */
+ ~nested_strict_lock()BOOST_NOEXCEPT
+ {
+ lk_ = move(tmp_lk_); /*< Move ownership to nesting lock >*/
+ }
+
+ // observers
+ /**
+ * return @c the owned mutex.
+ */
+ mutex_type* mutex() const BOOST_NOEXCEPT
+ {
+ return tmp_lk_.mutex();
+ }
+
+ /**
+ * @return whether this lock is locking a mutex.
+ */
+ bool owns_lock() const BOOST_NOEXCEPT
+ {
+ return true;
+ }
+
+ /**
+ * @return whether if this lock is locking that mutex.
+ */
+ bool owns_lock(mutex_type const* l) const BOOST_NOEXCEPT
+ {
+ return l == mutex();
+ }
+
+ //BOOST_ADRESS_OF_DELETE(nested_strict_lock)
+ //BOOST_HEAP_ALLOCATEION_DELETE(nested_strict_lock)
+
+ private:
+ Lock& lk_;
+ Lock tmp_lk_;
+ };
+ //]
+
+ template <typename Lock>
+ struct is_strict_lock_sur_parole<nested_strict_lock<Lock> > : true_type
+ {
+ };
+
+#if ! defined BOOST_THREAD_NO_MAKE_STRICT_LOCK
+ template <typename Lockable>
+ strict_lock<Lockable> make_strict_lock(Lockable& mtx)
+ {
+ return { thread_detail::lockable_wrapper<Lockable>(mtx) };
+ }
+ template <typename Lock>
+ nested_strict_lock<Lock> make_nested_strict_lock(Lock& lk)
+ {
+ return { thread_detail::lockable_wrapper<Lock>(lk) };
+ }
+#endif
+}
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/sync_bounded_queue.hpp b/src/third_party/boost-1.60.0/boost/thread/sync_bounded_queue.hpp
new file mode 100644
index 00000000000..2024d6602e4
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/sync_bounded_queue.hpp
@@ -0,0 +1,16 @@
+#ifndef BOOST_THREAD_SYNC_BOUNDED_QUEUE_HPP
+#define BOOST_THREAD_SYNC_BOUNDED_QUEUE_HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2013-2014. Distributed under the 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 http://www.boost.org/libs/thread for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/thread/concurrent_queues/sync_bounded_queue.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/sync_queue.hpp b/src/third_party/boost-1.60.0/boost/thread/sync_queue.hpp
new file mode 100644
index 00000000000..0d9334b4783
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/sync_queue.hpp
@@ -0,0 +1,16 @@
+#ifndef BOOST_THREAD_SYNC_QUEUE_HPP
+#define BOOST_THREAD_SYNC_QUEUE_HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2013-2014. Distributed under the 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 http://www.boost.org/libs/thread for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/thread/concurrent_queues/sync_queue.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/synchronized_value.hpp b/src/third_party/boost-1.60.0/boost/thread/synchronized_value.hpp
new file mode 100644
index 00000000000..e161063040f
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/synchronized_value.hpp
@@ -0,0 +1,1068 @@
+// (C) Copyright 2010 Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk
+// (C) Copyright 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)
+
+
+#ifndef BOOST_THREAD_SYNCHRONIZED_VALUE_HPP
+#define BOOST_THREAD_SYNCHRONIZED_VALUE_HPP
+
+#include <boost/thread/detail/config.hpp>
+
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/lock_guard.hpp>
+#include <boost/thread/lock_algorithms.hpp>
+#include <boost/thread/lock_factories.hpp>
+#include <boost/thread/strict_lock.hpp>
+#include <boost/core/swap.hpp>
+#include <boost/utility/declval.hpp>
+//#include <boost/type_traits.hpp>
+//#include <boost/thread/detail/is_nothrow_default_constructible.hpp>
+//#if ! defined BOOST_NO_CXX11_HDR_TYPE_TRAITS
+//#include <type_traits>
+//#endif
+
+#if ! defined(BOOST_THREAD_NO_SYNCHRONIZE)
+#include <tuple> // todo change to <boost/tuple.hpp> once Boost.Tuple or Boost.Fusion provides Move semantics on C++98 compilers.
+#include <functional>
+#endif
+
+#include <boost/utility/result_of.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+
+ /**
+ * strict lock providing a const pointer access to the synchronized value type.
+ *
+ * @param T the value type.
+ * @param Lockable the mutex type protecting the value type.
+ */
+ template <typename T, typename Lockable = mutex>
+ class const_strict_lock_ptr
+ {
+ public:
+ typedef T value_type;
+ typedef Lockable mutex_type;
+ protected:
+
+ // this should be a strict_lock, but unique_lock is needed to be able to return it.
+ boost::unique_lock<mutex_type> lk_;
+ T const& value_;
+
+ public:
+ BOOST_THREAD_MOVABLE_ONLY( const_strict_lock_ptr )
+
+ /**
+ * @param value constant reference of the value to protect.
+ * @param mtx reference to the mutex used to protect the value.
+ * @effects locks the mutex @c mtx, stores a reference to it and to the value type @c value.
+ */
+ const_strict_lock_ptr(T const& val, Lockable & mtx) :
+ lk_(mtx), value_(val)
+ {
+ }
+ const_strict_lock_ptr(T const& val, Lockable & mtx, adopt_lock_t tag) BOOST_NOEXCEPT :
+ lk_(mtx, tag), value_(val)
+ {
+ }
+ /**
+ * Move constructor.
+ * @effects takes ownership of the mutex owned by @c other, stores a reference to the mutex and the value type of @c other.
+ */
+ const_strict_lock_ptr(BOOST_THREAD_RV_REF(const_strict_lock_ptr) other) BOOST_NOEXCEPT
+ : lk_(boost::move(BOOST_THREAD_RV(other).lk_)),value_(BOOST_THREAD_RV(other).value_)
+ {
+ }
+
+ ~const_strict_lock_ptr()
+ {
+ }
+
+ /**
+ * @return a constant pointer to the protected value
+ */
+ const T* operator->() const
+ {
+ return &value_;
+ }
+
+ /**
+ * @return a constant reference to the protected value
+ */
+ const T& operator*() const
+ {
+ return value_;
+ }
+
+ };
+
+ /**
+ * strict lock providing a pointer access to the synchronized value type.
+ *
+ * @param T the value type.
+ * @param Lockable the mutex type protecting the value type.
+ */
+ template <typename T, typename Lockable = mutex>
+ class strict_lock_ptr : public const_strict_lock_ptr<T,Lockable>
+ {
+ typedef const_strict_lock_ptr<T,Lockable> base_type;
+ public:
+ BOOST_THREAD_MOVABLE_ONLY( strict_lock_ptr )
+
+ /**
+ * @param value reference of the value to protect.
+ * @param mtx reference to the mutex used to protect the value.
+ * @effects locks the mutex @c mtx, stores a reference to it and to the value type @c value.
+ */
+ strict_lock_ptr(T & val, Lockable & mtx) :
+ base_type(val, mtx)
+ {
+ }
+ strict_lock_ptr(T & val, Lockable & mtx, adopt_lock_t tag) :
+ base_type(val, mtx, tag)
+ {
+ }
+
+ /**
+ * Move constructor.
+ * @effects takes ownership of the mutex owned by @c other, stores a reference to the mutex and the value type of @c other.
+ */
+ strict_lock_ptr(BOOST_THREAD_RV_REF(strict_lock_ptr) other)
+ : base_type(boost::move(static_cast<base_type&>(other)))
+ {
+ }
+
+ ~strict_lock_ptr()
+ {
+ }
+
+ /**
+ * @return a pointer to the protected value
+ */
+ T* operator->()
+ {
+ return const_cast<T*>(&this->value_);
+ }
+
+ /**
+ * @return a reference to the protected value
+ */
+ T& operator*()
+ {
+ return const_cast<T&>(this->value_);
+ }
+
+ };
+
+ template <typename SV>
+ struct synchronized_value_strict_lock_ptr
+ {
+ typedef strict_lock_ptr<typename SV::value_type, typename SV::mutex_type> type;
+ };
+
+ template <typename SV>
+ struct synchronized_value_strict_lock_ptr<const SV>
+ {
+ typedef const_strict_lock_ptr<typename SV::value_type, typename SV::mutex_type> type;
+ };
+ /**
+ * unique_lock providing a const pointer access to the synchronized value type.
+ *
+ * An object of type const_unique_lock_ptr is a unique_lock that provides a const pointer access to the synchronized value type.
+ * As unique_lock controls the ownership of a lockable object within a scope.
+ * Ownership of the lockable object may be acquired at construction or after construction,
+ * and may be transferred, after acquisition, to another const_unique_lock_ptr object.
+ * Objects of type const_unique_lock_ptr are not copyable but are movable.
+ * The behavior of a program is undefined if the mutex and the value type
+ * pointed do not exist for the entire remaining lifetime of the const_unique_lock_ptr object.
+ * The supplied Mutex type shall meet the BasicLockable requirements.
+ *
+ * @note const_unique_lock_ptr<T, Lockable> meets the Lockable requirements.
+ * If Lockable meets the TimedLockable requirements, const_unique_lock_ptr<T,Lockable>
+ * also meets the TimedLockable requirements.
+ *
+ * @param T the value type.
+ * @param Lockable the mutex type protecting the value type.
+ */
+ template <typename T, typename Lockable = mutex>
+ class const_unique_lock_ptr : public unique_lock<Lockable>
+ {
+ typedef unique_lock<Lockable> base_type;
+ public:
+ typedef T value_type;
+ typedef Lockable mutex_type;
+ protected:
+ T const& value_;
+
+ public:
+ BOOST_THREAD_MOVABLE_ONLY(const_unique_lock_ptr)
+
+ /**
+ * @param value reference of the value to protect.
+ * @param mtx reference to the mutex used to protect the value.
+ *
+ * @requires If mutex_type is not a recursive mutex the calling thread does not own the mutex.
+ *
+ * @effects locks the mutex @c mtx, stores a reference to it and to the value type @c value.
+ */
+ const_unique_lock_ptr(T const& val, Lockable & mtx)
+ : base_type(mtx), value_(val)
+ {
+ }
+ /**
+ * @param value reference of the value to protect.
+ * @param mtx reference to the mutex used to protect the value.
+ * @param tag of type adopt_lock_t used to differentiate the constructor.
+ * @requires The calling thread own the mutex.
+ * @effects stores a reference to it and to the value type @c value taking ownership.
+ */
+ const_unique_lock_ptr(T const& val, Lockable & mtx, adopt_lock_t) BOOST_NOEXCEPT
+ : base_type(mtx, adopt_lock), value_(val)
+ {
+ }
+ /**
+ * @param value reference of the value to protect.
+ * @param mtx reference to the mutex used to protect the value.
+ * @param tag of type defer_lock_t used to differentiate the constructor.
+ * @effects stores a reference to it and to the value type @c value c.
+ */
+ const_unique_lock_ptr(T const& val, Lockable & mtx, defer_lock_t) BOOST_NOEXCEPT
+ : base_type(mtx, defer_lock), value_(val)
+ {
+ }
+ /**
+ * @param value reference of the value to protect.
+ * @param mtx reference to the mutex used to protect the value.
+ * @param tag of type try_to_lock_t used to differentiate the constructor.
+ * @requires If mutex_type is not a recursive mutex the calling thread does not own the mutex.
+ * @effects try to lock the mutex @c mtx, stores a reference to it and to the value type @c value.
+ */
+ const_unique_lock_ptr(T const& val, Lockable & mtx, try_to_lock_t) BOOST_NOEXCEPT
+ : base_type(mtx, try_to_lock), value_(val)
+ {
+ }
+ /**
+ * Move constructor.
+ * @effects takes ownership of the mutex owned by @c other, stores a reference to the mutex and the value type of @c other.
+ */
+ const_unique_lock_ptr(BOOST_THREAD_RV_REF(const_unique_lock_ptr) other) BOOST_NOEXCEPT
+ : base_type(boost::move(static_cast<base_type&>(other))), value_(BOOST_THREAD_RV(other).value_)
+ {
+ }
+
+ /**
+ * @effects If owns calls unlock() on the owned mutex.
+ */
+ ~const_unique_lock_ptr()
+ {
+ }
+
+ /**
+ * @return a constant pointer to the protected value
+ */
+ const T* operator->() const
+ {
+ BOOST_ASSERT (this->owns_lock());
+ return &value_;
+ }
+
+ /**
+ * @return a constant reference to the protected value
+ */
+ const T& operator*() const
+ {
+ BOOST_ASSERT (this->owns_lock());
+ return value_;
+ }
+
+ };
+
+ /**
+ * unique lock providing a pointer access to the synchronized value type.
+ *
+ * @param T the value type.
+ * @param Lockable the mutex type protecting the value type.
+ */
+ template <typename T, typename Lockable = mutex>
+ class unique_lock_ptr : public const_unique_lock_ptr<T, Lockable>
+ {
+ typedef const_unique_lock_ptr<T, Lockable> base_type;
+ public:
+ typedef T value_type;
+ typedef Lockable mutex_type;
+
+ BOOST_THREAD_MOVABLE_ONLY(unique_lock_ptr)
+
+ /**
+ * @param value reference of the value to protect.
+ * @param mtx reference to the mutex used to protect the value.
+ * @effects locks the mutex @c mtx, stores a reference to it and to the value type @c value.
+ */
+ unique_lock_ptr(T & val, Lockable & mtx)
+ : base_type(val, mtx)
+ {
+ }
+ /**
+ * @param value reference of the value to protect.
+ * @param mtx reference to the mutex used to protect the value.
+ * @param tag of type adopt_lock_t used to differentiate the constructor.
+ * @effects stores a reference to it and to the value type @c value taking ownership.
+ */
+ unique_lock_ptr(T & value, Lockable & mtx, adopt_lock_t) BOOST_NOEXCEPT
+ : base_type(value, mtx, adopt_lock)
+ {
+ }
+ /**
+ * @param value reference of the value to protect.
+ * @param mtx reference to the mutex used to protect the value.
+ * @param tag of type defer_lock_t used to differentiate the constructor.
+ * @effects stores a reference to it and to the value type @c value c.
+ */
+ unique_lock_ptr(T & value, Lockable & mtx, defer_lock_t) BOOST_NOEXCEPT
+ : base_type(value, mtx, defer_lock)
+ {
+ }
+ /**
+ * @param value reference of the value to protect.
+ * @param mtx reference to the mutex used to protect the value.
+ * @param tag of type try_to_lock_t used to differentiate the constructor.
+ * @effects try to lock the mutex @c mtx, stores a reference to it and to the value type @c value.
+ */
+ unique_lock_ptr(T & value, Lockable & mtx, try_to_lock_t) BOOST_NOEXCEPT
+ : base_type(value, mtx, try_to_lock)
+ {
+ }
+ /**
+ * Move constructor.
+ * @effects takes ownership of the mutex owned by @c other, stores a reference to the mutex and the value type of @c other.
+ */
+ unique_lock_ptr(BOOST_THREAD_RV_REF(unique_lock_ptr) other) BOOST_NOEXCEPT
+ : base_type(boost::move(static_cast<base_type&>(other)))
+ {
+ }
+
+ ~unique_lock_ptr()
+ {
+ }
+
+ /**
+ * @return a pointer to the protected value
+ */
+ T* operator->()
+ {
+ BOOST_ASSERT (this->owns_lock());
+ return const_cast<T*>(&this->value_);
+ }
+
+ /**
+ * @return a reference to the protected value
+ */
+ T& operator*()
+ {
+ BOOST_ASSERT (this->owns_lock());
+ return const_cast<T&>(this->value_);
+ }
+
+
+ };
+
+ template <typename SV>
+ struct synchronized_value_unique_lock_ptr
+ {
+ typedef unique_lock_ptr<typename SV::value_type, typename SV::mutex_type> type;
+ };
+
+ template <typename SV>
+ struct synchronized_value_unique_lock_ptr<const SV>
+ {
+ typedef const_unique_lock_ptr<typename SV::value_type, typename SV::mutex_type> type;
+ };
+ /**
+ * cloaks a value type and the mutex used to protect it together.
+ * @param T the value type.
+ * @param Lockable the mutex type protecting the value type.
+ */
+ template <typename T, typename Lockable = mutex>
+ class synchronized_value
+ {
+
+#if ! defined(BOOST_THREAD_NO_MAKE_UNIQUE_LOCKS)
+#if ! defined BOOST_NO_CXX11_VARIADIC_TEMPLATES
+ template <typename ...SV>
+ friend std::tuple<typename synchronized_value_strict_lock_ptr<SV>::type ...> synchronize(SV& ...sv);
+#else
+ template <typename SV1, typename SV2>
+ friend std::tuple<
+ typename synchronized_value_strict_lock_ptr<SV1>::type,
+ typename synchronized_value_strict_lock_ptr<SV2>::type
+ >
+ synchronize(SV1& sv1, SV2& sv2);
+ template <typename SV1, typename SV2, typename SV3>
+ friend std::tuple<
+ typename synchronized_value_strict_lock_ptr<SV1>::type,
+ typename synchronized_value_strict_lock_ptr<SV2>::type,
+ typename synchronized_value_strict_lock_ptr<SV3>::type
+ >
+ synchronize(SV1& sv1, SV2& sv2, SV3& sv3);
+#endif
+#endif
+
+ public:
+ typedef T value_type;
+ typedef Lockable mutex_type;
+ private:
+ T value_;
+ mutable mutex_type mtx_;
+ public:
+ // construction/destruction
+ /**
+ * Default constructor.
+ *
+ * @Requires: T is DefaultConstructible
+ */
+ synchronized_value()
+ //BOOST_NOEXCEPT_IF(is_nothrow_default_constructible<T>::value)
+ : value_()
+ {
+ }
+
+ /**
+ * Constructor from copy constructible value.
+ *
+ * Requires: T is CopyConstructible
+ */
+ synchronized_value(T const& other)
+ //BOOST_NOEXCEPT_IF(is_nothrow_copy_constructible<T>::value)
+ : value_(other)
+ {
+ }
+
+ /**
+ * Move Constructor.
+ *
+ * Requires: T is CopyMovable
+ */
+ synchronized_value(BOOST_THREAD_RV_REF(T) other)
+ //BOOST_NOEXCEPT_IF(is_nothrow_move_constructible<T>::value)
+ : value_(boost::move(other))
+ {
+ }
+
+ /**
+ * Constructor from value type.
+ *
+ * Requires: T is DefaultConstructible and Assignable
+ * Effects: Assigns the value on a scope protected by the mutex of the rhs. The mutex is not copied.
+ */
+ synchronized_value(synchronized_value const& rhs)
+ {
+ strict_lock<mutex_type> lk(rhs.mtx_);
+ value_ = rhs.value_;
+ }
+
+ /**
+ * Move Constructor from movable value type
+ *
+ */
+ synchronized_value(BOOST_THREAD_RV_REF(synchronized_value) other)
+ {
+ strict_lock<mutex_type> lk(BOOST_THREAD_RV(other).mtx_);
+ value_= boost::move(BOOST_THREAD_RV(other).value_);
+ }
+
+ // mutation
+ /**
+ * Assignment operator.
+ *
+ * Effects: Copies the underlying value on a scope protected by the two mutexes.
+ * The mutex is not copied. The locks are acquired using lock, so deadlock is avoided.
+ * For example, there is no problem if one thread assigns a = b and the other assigns b = a.
+ *
+ * Return: *this
+ */
+
+ synchronized_value& operator=(synchronized_value const& rhs)
+ {
+ if(&rhs != this)
+ {
+ // auto _ = make_unique_locks(mtx_, rhs.mtx_);
+ unique_lock<mutex_type> lk1(mtx_, defer_lock);
+ unique_lock<mutex_type> lk2(rhs.mtx_, defer_lock);
+ lock(lk1,lk2);
+
+ value_ = rhs.value_;
+ }
+ return *this;
+ }
+ /**
+ * Assignment operator from a T const&.
+ * Effects: The operator copies the value on a scope protected by the mutex.
+ * Return: *this
+ */
+ synchronized_value& operator=(value_type const& val)
+ {
+ {
+ strict_lock<mutex_type> lk(mtx_);
+ value_ = val;
+ }
+ return *this;
+ }
+
+ //observers
+ /**
+ * Explicit conversion to value type.
+ *
+ * Requires: T is CopyConstructible
+ * Return: A copy of the protected value obtained on a scope protected by the mutex.
+ *
+ */
+ T get() const
+ {
+ strict_lock<mutex_type> lk(mtx_);
+ return value_;
+ }
+ /**
+ * Explicit conversion to value type.
+ *
+ * Requires: T is CopyConstructible
+ * Return: A copy of the protected value obtained on a scope protected by the mutex.
+ *
+ */
+#if ! defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
+ explicit operator T() const
+ {
+ return get();
+ }
+#endif
+
+ /**
+ * value type getter.
+ *
+ * Return: A constant reference to the protected value.
+ *
+ * Note: Not thread safe
+ *
+ */
+ T const& value() const
+ {
+ return value_;
+ }
+ /**
+ * mutex getter.
+ *
+ * Return: A constant reference to the protecting mutex.
+ *
+ * Note: Not thread safe
+ *
+ */
+ mutex_type const& mutex() const
+ {
+ return mtx_;
+ }
+ /**
+ * Swap
+ *
+ * Effects: Swaps the data. Again, locks are acquired using lock(). The mutexes are not swapped.
+ * A swap method accepts a T& and swaps the data inside a critical section.
+ * This is by far the preferred method of changing the guarded datum wholesale because it keeps the lock only
+ * for a short time, thus lowering the pressure on the mutex.
+ */
+ void swap(synchronized_value & rhs)
+ {
+ if (this == &rhs) {
+ return;
+ }
+ // auto _ = make_unique_locks(mtx_, rhs.mtx_);
+ unique_lock<mutex_type> lk1(mtx_, defer_lock);
+ unique_lock<mutex_type> lk2(rhs.mtx_, defer_lock);
+ lock(lk1,lk2);
+ boost::swap(value_, rhs.value_);
+ }
+ /**
+ * Swap with the underlying value type
+ *
+ * Effects: Swaps the data on a scope protected by the mutex.
+ */
+ void swap(value_type & rhs)
+ {
+ strict_lock<mutex_type> lk(mtx_);
+ boost::swap(value_, rhs);
+ }
+
+ /**
+ * Essentially calling a method obj->foo(x, y, z) calls the method foo(x, y, z) inside a critical section as
+ * long-lived as the call itself.
+ */
+ strict_lock_ptr<T,Lockable> operator->()
+ {
+ return BOOST_THREAD_MAKE_RV_REF((strict_lock_ptr<T,Lockable>(value_, mtx_)));
+ }
+ /**
+ * If the synchronized_value object involved is const-qualified, then you'll only be able to call const methods
+ * through operator->. So, for example, vec->push_back("xyz") won't work if vec were const-qualified.
+ * The locking mechanism capitalizes on the assumption that const methods don't modify their underlying data.
+ */
+ const_strict_lock_ptr<T,Lockable> operator->() const
+ {
+ return BOOST_THREAD_MAKE_RV_REF((const_strict_lock_ptr<T,Lockable>(value_, mtx_)));
+ }
+
+ /**
+ * Call function on a locked block.
+ *
+ * @requires fct(value_) is well formed.
+ *
+ * Example
+ * void fun(synchronized_value<vector<int>> & v) {
+ * v ( [](vector<int>> & vec)
+ * {
+ * vec.push_back(42);
+ * assert(vec.back() == 42);
+ * } );
+ * }
+ */
+ template <typename F>
+ inline
+ typename boost::result_of<F(value_type&)>::type
+ operator()(BOOST_THREAD_RV_REF(F) fct)
+ {
+ strict_lock<mutex_type> lk(mtx_);
+ return fct(value_);
+ }
+ template <typename F>
+ inline
+ typename boost::result_of<F(value_type const&)>::type
+ operator()(BOOST_THREAD_RV_REF(F) fct) const
+ {
+ strict_lock<mutex_type> lk(mtx_);
+ return fct(value_);
+ }
+
+
+#if defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ template <typename F>
+ inline
+ typename boost::result_of<F(value_type&)>::type
+ operator()(F const & fct)
+ {
+ strict_lock<mutex_type> lk(mtx_);
+ return fct(value_);
+ }
+ template <typename F>
+ inline
+ typename boost::result_of<F(value_type const&)>::type
+ operator()(F const & fct) const
+ {
+ strict_lock<mutex_type> lk(mtx_);
+ return fct(value_);
+ }
+
+ template <typename R>
+ inline
+ R operator()(R(*fct)(value_type&))
+ {
+ strict_lock<mutex_type> lk(mtx_);
+ return fct(value_);
+ }
+ template <typename R>
+ inline
+ R operator()(R(*fct)(value_type const&)) const
+ {
+ strict_lock<mutex_type> lk(mtx_);
+ return fct(value_);
+ }
+#endif
+
+
+ /**
+ * The synchronize() factory make easier to lock on a scope.
+ * As discussed, operator-> can only lock over the duration of a call, so it is insufficient for complex operations.
+ * With synchronize() you get to lock the object in a scoped and to directly access the object inside that scope.
+ *
+ * Example
+ * void fun(synchronized_value<vector<int>> & v) {
+ * auto&& vec=v.synchronize();
+ * vec.push_back(42);
+ * assert(vec.back() == 42);
+ * }
+ */
+ strict_lock_ptr<T,Lockable> synchronize()
+ {
+ return BOOST_THREAD_MAKE_RV_REF((strict_lock_ptr<T,Lockable>(value_, mtx_)));
+ }
+ const_strict_lock_ptr<T,Lockable> synchronize() const
+ {
+ return BOOST_THREAD_MAKE_RV_REF((const_strict_lock_ptr<T,Lockable>(value_, mtx_)));
+ }
+
+ unique_lock_ptr<T,Lockable> unique_synchronize()
+ {
+ return BOOST_THREAD_MAKE_RV_REF((unique_lock_ptr<T,Lockable>(value_, mtx_)));
+ }
+ const_unique_lock_ptr<T,Lockable> unique_synchronize() const
+ {
+ return BOOST_THREAD_MAKE_RV_REF((const_unique_lock_ptr<T,Lockable>(value_, mtx_)));
+ }
+ unique_lock_ptr<T,Lockable> unique_synchronize(defer_lock_t tag)
+ {
+ return BOOST_THREAD_MAKE_RV_REF((unique_lock_ptr<T,Lockable>(value_, mtx_, tag)));
+ }
+ const_unique_lock_ptr<T,Lockable> unique_synchronize(defer_lock_t tag) const
+ {
+ return BOOST_THREAD_MAKE_RV_REF((const_unique_lock_ptr<T,Lockable>(value_, mtx_, tag)));
+ }
+ unique_lock_ptr<T,Lockable> defer_synchronize() BOOST_NOEXCEPT
+ {
+ return BOOST_THREAD_MAKE_RV_REF((unique_lock_ptr<T,Lockable>(value_, mtx_, defer_lock)));
+ }
+ const_unique_lock_ptr<T,Lockable> defer_synchronize() const BOOST_NOEXCEPT
+ {
+ return BOOST_THREAD_MAKE_RV_REF((const_unique_lock_ptr<T,Lockable>(value_, mtx_, defer_lock)));
+ }
+ unique_lock_ptr<T,Lockable> try_to_synchronize() BOOST_NOEXCEPT
+ {
+ return BOOST_THREAD_MAKE_RV_REF((unique_lock_ptr<T,Lockable>(value_, mtx_, try_to_lock)));
+ }
+ const_unique_lock_ptr<T,Lockable> try_to_synchronize() const BOOST_NOEXCEPT
+ {
+ return BOOST_THREAD_MAKE_RV_REF((const_unique_lock_ptr<T,Lockable>(value_, mtx_, try_to_lock)));
+ }
+ unique_lock_ptr<T,Lockable> adopt_synchronize() BOOST_NOEXCEPT
+ {
+ return BOOST_THREAD_MAKE_RV_REF((unique_lock_ptr<T,Lockable>(value_, mtx_, adopt_lock)));
+ }
+ const_unique_lock_ptr<T,Lockable> adopt_synchronize() const BOOST_NOEXCEPT
+ {
+ return BOOST_THREAD_MAKE_RV_REF((const_unique_lock_ptr<T,Lockable>(value_, mtx_, adopt_lock)));
+ }
+
+
+#if ! defined __IBMCPP__
+ private:
+#endif
+ class deref_value
+ {
+ private:
+ friend class synchronized_value;
+
+ boost::unique_lock<mutex_type> lk_;
+ T& value_;
+
+ explicit deref_value(synchronized_value& outer):
+ lk_(outer.mtx_),value_(outer.value_)
+ {}
+
+ public:
+ BOOST_THREAD_MOVABLE_ONLY(deref_value)
+
+ deref_value(BOOST_THREAD_RV_REF(deref_value) other):
+ lk_(boost::move(BOOST_THREAD_RV(other).lk_)),value_(BOOST_THREAD_RV(other).value_)
+ {}
+ operator T&()
+ {
+ return value_;
+ }
+
+ deref_value& operator=(T const& newVal)
+ {
+ value_=newVal;
+ return *this;
+ }
+ };
+ class const_deref_value
+ {
+ private:
+ friend class synchronized_value;
+
+ boost::unique_lock<mutex_type> lk_;
+ const T& value_;
+
+ explicit const_deref_value(synchronized_value const& outer):
+ lk_(outer.mtx_), value_(outer.value_)
+ {}
+
+ public:
+ BOOST_THREAD_MOVABLE_ONLY(const_deref_value)
+
+ const_deref_value(BOOST_THREAD_RV_REF(const_deref_value) other):
+ lk_(boost::move(BOOST_THREAD_RV(other).lk_)), value_(BOOST_THREAD_RV(other).value_)
+ {}
+
+ operator const T&()
+ {
+ return value_;
+ }
+ };
+
+ public:
+ deref_value operator*()
+ {
+ return BOOST_THREAD_MAKE_RV_REF(deref_value(*this));
+ }
+
+ const_deref_value operator*() const
+ {
+ return BOOST_THREAD_MAKE_RV_REF(const_deref_value(*this));
+ }
+
+ // io functions
+ /**
+ * @requires T is OutputStreamable
+ * @effects saves the value type on the output stream @c os.
+ */
+ template <typename OStream>
+ void save(OStream& os) const
+ {
+ strict_lock<mutex_type> lk(mtx_);
+ os << value_;
+ }
+ /**
+ * @requires T is InputStreamable
+ * @effects loads the value type from the input stream @c is.
+ */
+ template <typename IStream>
+ void load(IStream& is) const
+ {
+ strict_lock<mutex_type> lk(mtx_);
+ is >> value_;
+ }
+
+ // relational operators
+ /**
+ * @requires T is EqualityComparable
+ *
+ */
+ bool operator==(synchronized_value const& rhs) const
+ {
+ unique_lock<mutex_type> lk1(mtx_, defer_lock);
+ unique_lock<mutex_type> lk2(rhs.mtx_, defer_lock);
+ lock(lk1,lk2);
+
+ return value_ == rhs.value_;
+ }
+ /**
+ * @requires T is LessThanComparable
+ *
+ */
+ bool operator<(synchronized_value const& rhs) const
+ {
+ unique_lock<mutex_type> lk1(mtx_, defer_lock);
+ unique_lock<mutex_type> lk2(rhs.mtx_, defer_lock);
+ lock(lk1,lk2);
+
+ return value_ < rhs.value_;
+ }
+ /**
+ * @requires T is GreaterThanComparable
+ *
+ */
+ bool operator>(synchronized_value const& rhs) const
+ {
+ unique_lock<mutex_type> lk1(mtx_, defer_lock);
+ unique_lock<mutex_type> lk2(rhs.mtx_, defer_lock);
+ lock(lk1,lk2);
+
+ return value_ > rhs.value_;
+ }
+ bool operator<=(synchronized_value const& rhs) const
+ {
+ unique_lock<mutex_type> lk1(mtx_, defer_lock);
+ unique_lock<mutex_type> lk2(rhs.mtx_, defer_lock);
+ lock(lk1,lk2);
+
+ return value_ <= rhs.value_;
+ }
+ bool operator>=(synchronized_value const& rhs) const
+ {
+ unique_lock<mutex_type> lk1(mtx_, defer_lock);
+ unique_lock<mutex_type> lk2(rhs.mtx_, defer_lock);
+ lock(lk1,lk2);
+
+ return value_ >= rhs.value_;
+ }
+ bool operator==(value_type const& rhs) const
+ {
+ unique_lock<mutex_type> lk1(mtx_);
+
+ return value_ == rhs;
+ }
+ bool operator!=(value_type const& rhs) const
+ {
+ unique_lock<mutex_type> lk1(mtx_);
+
+ return value_ != rhs;
+ }
+ bool operator<(value_type const& rhs) const
+ {
+ unique_lock<mutex_type> lk1(mtx_);
+
+ return value_ < rhs;
+ }
+ bool operator<=(value_type const& rhs) const
+ {
+ unique_lock<mutex_type> lk1(mtx_);
+
+ return value_ <= rhs;
+ }
+ bool operator>(value_type const& rhs) const
+ {
+ unique_lock<mutex_type> lk1(mtx_);
+
+ return value_ > rhs;
+ }
+ bool operator>=(value_type const& rhs) const
+ {
+ unique_lock<mutex_type> lk1(mtx_);
+
+ return value_ >= rhs;
+ }
+
+ };
+
+ // Specialized algorithms
+ /**
+ *
+ */
+ template <typename T, typename L>
+ inline void swap(synchronized_value<T,L> & lhs, synchronized_value<T,L> & rhs)
+ {
+ lhs.swap(rhs);
+ }
+ template <typename T, typename L>
+ inline void swap(synchronized_value<T,L> & lhs, T & rhs)
+ {
+ lhs.swap(rhs);
+ }
+ template <typename T, typename L>
+ inline void swap(T & lhs, synchronized_value<T,L> & rhs)
+ {
+ rhs.swap(lhs);
+ }
+
+ //Hash support
+
+// template <class T> struct hash;
+// template <typename T, typename L>
+// struct hash<synchronized_value<T,L> >;
+
+ // Comparison with T
+ template <typename T, typename L>
+ bool operator!=(synchronized_value<T,L> const&lhs, synchronized_value<T,L> const& rhs)
+ {
+ return ! (lhs==rhs);
+ }
+
+ template <typename T, typename L>
+ bool operator==(T const& lhs, synchronized_value<T,L> const&rhs)
+ {
+ return rhs==lhs;
+ }
+ template <typename T, typename L>
+ bool operator!=(T const& lhs, synchronized_value<T,L> const&rhs)
+ {
+ return rhs!=lhs;
+ }
+ template <typename T, typename L>
+ bool operator<(T const& lhs, synchronized_value<T,L> const&rhs)
+ {
+ return rhs>=lhs;
+ }
+ template <typename T, typename L>
+ bool operator<=(T const& lhs, synchronized_value<T,L> const&rhs)
+ {
+ return rhs>lhs;
+ }
+ template <typename T, typename L>
+ bool operator>(T const& lhs, synchronized_value<T,L> const&rhs)
+ {
+ return rhs<=lhs;
+ }
+ template <typename T, typename L>
+ bool operator>=(T const& lhs, synchronized_value<T,L> const&rhs)
+ {
+ return rhs<lhs;
+ }
+
+ /**
+ *
+ */
+ template <typename OStream, typename T, typename L>
+ inline OStream& operator<<(OStream& os, synchronized_value<T,L> const& rhs)
+ {
+ rhs.save(os);
+ return os;
+ }
+ template <typename IStream, typename T, typename L>
+ inline IStream& operator>>(IStream& is, synchronized_value<T,L> const& rhs)
+ {
+ rhs.load(is);
+ return is;
+ }
+
+#if ! defined(BOOST_THREAD_NO_SYNCHRONIZE)
+#if ! defined BOOST_NO_CXX11_VARIADIC_TEMPLATES
+
+ template <typename ...SV>
+ std::tuple<typename synchronized_value_strict_lock_ptr<SV>::type ...> synchronize(SV& ...sv)
+ {
+ boost::lock(sv.mtx_ ...);
+ typedef std::tuple<typename synchronized_value_strict_lock_ptr<SV>::type ...> t_type;
+
+ return t_type(typename synchronized_value_strict_lock_ptr<SV>::type(sv.value_, sv.mtx_, adopt_lock) ...);
+ }
+#else
+
+ template <typename SV1, typename SV2>
+ std::tuple<
+ typename synchronized_value_strict_lock_ptr<SV1>::type,
+ typename synchronized_value_strict_lock_ptr<SV2>::type
+ >
+ synchronize(SV1& sv1, SV2& sv2)
+ {
+ boost::lock(sv1.mtx_, sv2.mtx_);
+ typedef std::tuple<
+ typename synchronized_value_strict_lock_ptr<SV1>::type,
+ typename synchronized_value_strict_lock_ptr<SV2>::type
+ > t_type;
+
+ return t_type(
+ typename synchronized_value_strict_lock_ptr<SV1>::type(sv1.value_, sv1.mtx_, adopt_lock),
+ typename synchronized_value_strict_lock_ptr<SV2>::type(sv2.value_, sv2.mtx_, adopt_lock)
+ );
+
+ }
+ template <typename SV1, typename SV2, typename SV3>
+ std::tuple<
+ typename synchronized_value_strict_lock_ptr<SV1>::type,
+ typename synchronized_value_strict_lock_ptr<SV2>::type,
+ typename synchronized_value_strict_lock_ptr<SV3>::type
+ >
+ synchronize(SV1& sv1, SV2& sv2, SV3& sv3)
+ {
+ boost::lock(sv1.mtx_, sv2.mtx_);
+ typedef std::tuple<
+ typename synchronized_value_strict_lock_ptr<SV1>::type,
+ typename synchronized_value_strict_lock_ptr<SV2>::type,
+ typename synchronized_value_strict_lock_ptr<SV3>::type
+ > t_type;
+
+ return t_type(
+ typename synchronized_value_strict_lock_ptr<SV1>::type(sv1.value_, sv1.mtx_, adopt_lock),
+ typename synchronized_value_strict_lock_ptr<SV2>::type(sv2.value_, sv2.mtx_, adopt_lock),
+ typename synchronized_value_strict_lock_ptr<SV3>::type(sv3.value_, sv3.mtx_, adopt_lock)
+ );
+
+ }
+#endif
+#endif
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/testable_mutex.hpp b/src/third_party/boost-1.60.0/boost/thread/testable_mutex.hpp
new file mode 100644
index 00000000000..3c87f9349a5
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/testable_mutex.hpp
@@ -0,0 +1,152 @@
+// (C) Copyright 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)
+
+
+#ifndef BOOST_THREAD_TESTABLE_LOCKABLE_HPP
+#define BOOST_THREAD_TESTABLE_LOCKABLE_HPP
+
+#include <boost/thread/detail/config.hpp>
+
+#include <boost/thread/thread_only.hpp>
+
+#include <boost/atomic.hpp>
+#include <boost/assert.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ /**
+ * Based on Associate Mutexes with Data to Prevent Races, By Herb Sutter, May 13, 2010
+ * http://www.drdobbs.com/windows/associate-mutexes-with-data-to-prevent-r/224701827?pgno=3
+ *
+ * Make our mutex testable if it isn't already.
+ *
+ * Many mutex services (including boost::mutex) don't provide a way to ask,
+ * "Do I already hold a lock on this mutex?"
+ * Sometimes it is needed to know if a method like is_locked to be available.
+ * This wrapper associates an arbitrary lockable type with a thread id that stores the ID of the thread that
+ * currently holds the lockable. The thread id initially holds an invalid value that means no threads own the mutex.
+ * When we acquire a lock, we set the thread id; and when we release a lock, we reset it back to its default no id state.
+ *
+ */
+ template <typename Lockable>
+ class testable_mutex
+ {
+ Lockable mtx_;
+ atomic<thread::id> id_;
+ public:
+ /// the type of the wrapped lockable
+ typedef Lockable lockable_type;
+
+ /// Non copyable
+ BOOST_THREAD_NO_COPYABLE(testable_mutex)
+
+ testable_mutex() : id_(thread::id()) {}
+
+ void lock()
+ {
+ BOOST_ASSERT(! is_locked_by_this_thread());
+ mtx_.lock();
+ id_ = this_thread::get_id();
+ }
+
+ void unlock()
+ {
+ BOOST_ASSERT(is_locked_by_this_thread());
+ id_ = thread::id();
+ mtx_.unlock();
+ }
+
+ bool try_lock()
+ {
+ BOOST_ASSERT(! is_locked_by_this_thread());
+ if (mtx_.try_lock())
+ {
+ id_ = this_thread::get_id();
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
+ {
+ BOOST_ASSERT(! is_locked_by_this_thread());
+ if (mtx_.try_lock_for(rel_time))
+ {
+ id_ = this_thread::get_id();
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ template <class Clock, class Duration>
+ bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
+ {
+ BOOST_ASSERT(! is_locked_by_this_thread());
+ if (mtx_.try_lock_until(abs_time))
+ {
+ id_ = this_thread::get_id();
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+#endif
+
+ bool is_locked_by_this_thread() const
+ {
+ return this_thread::get_id() == id_;
+ }
+ bool is_locked() const
+ {
+ return ! (thread::id() == id_);
+ }
+
+ thread::id get_id() const
+ {
+ return id_;
+ }
+
+ // todo add the shared and upgrade mutex functions
+ };
+
+ template <typename Lockable>
+ struct is_testable_lockable : false_type
+ {};
+
+ template <typename Lockable>
+ struct is_testable_lockable<testable_mutex<Lockable> > : true_type
+ {};
+
+// /**
+// * Overloaded function used to check if the mutex is locked when it is testable and do nothing otherwise.
+// *
+// * This function is used usually to assert the pre-condition when the function can only be called when the mutex
+// * must be locked by the current thread.
+// */
+// template <typename Lockable>
+// bool is_locked_by_this_thread(testable_mutex<Lockable> const& mtx)
+// {
+// return mtx.is_locked();
+// }
+// template <typename Lockable>
+// bool is_locked_by_this_thread(Lockable const&)
+// {
+// return true;
+// }
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // header
diff --git a/src/third_party/boost-1.60.0/boost/thread/thread.hpp b/src/third_party/boost-1.60.0/boost/thread/thread.hpp
new file mode 100644
index 00000000000..3e63b42aaa1
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/thread.hpp
@@ -0,0 +1,16 @@
+#ifndef BOOST_THREAD_THREAD_HPP
+#define BOOST_THREAD_THREAD_HPP
+
+// thread.hpp
+//
+// (C) Copyright 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)
+
+#include <boost/thread/thread_only.hpp>
+#include <boost/thread/detail/thread_group.hpp>
+
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/thread_functors.hpp b/src/third_party/boost-1.60.0/boost/thread/thread_functors.hpp
new file mode 100644
index 00000000000..f7bd816b178
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/thread_functors.hpp
@@ -0,0 +1,57 @@
+// Distributed under the 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 2009-2012 Anthony Williams
+// (C) Copyright 2012 Vicente J. Botet Escriba
+
+// Based on the Anthony's idea of scoped_thread in CCiA
+
+#ifndef BOOST_THREAD_THREAD_FUNCTORS_HPP
+#define BOOST_THREAD_THREAD_FUNCTORS_HPP
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/detail/delete.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/thread_only.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+
+ struct detach
+ {
+ void operator()(thread& t)
+ {
+ t.detach();
+ }
+ };
+
+ struct join_if_joinable
+ {
+ void operator()(thread& t)
+ {
+ if (t.joinable())
+ {
+ t.join();
+ }
+ }
+ };
+
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ struct interrupt_and_join_if_joinable
+ {
+ void operator()(thread& t)
+ {
+ t.interrupt();
+ if (t.joinable())
+ {
+ t.join();
+ }
+ }
+ };
+#endif
+}
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/thread_guard.hpp b/src/third_party/boost-1.60.0/boost/thread/thread_guard.hpp
new file mode 100644
index 00000000000..85157f101e2
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/thread_guard.hpp
@@ -0,0 +1,46 @@
+// Distributed under the 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 2009-2012 Anthony Williams
+// (C) Copyright 2012 Vicente J. Botet Escriba
+
+// Based on the Anthony's idea of thread_joiner in CCiA
+
+#ifndef BOOST_THREAD_THREAD_GUARD_HPP
+#define BOOST_THREAD_THREAD_GUARD_HPP
+
+#include <boost/thread/detail/delete.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/thread_functors.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+
+ /**
+ * Non-copyable RAII scoped thread guard joiner which join the thread if joinable when destroyed.
+ */
+ template <class CallableThread = join_if_joinable>
+ class thread_guard
+ {
+ thread& t_;
+ public:
+ BOOST_THREAD_NO_COPYABLE( thread_guard)
+
+ explicit thread_guard(thread& t) :
+ t_(t)
+ {
+ }
+ ~thread_guard()
+ {
+ CallableThread on_destructor;
+
+ on_destructor(t_);
+ }
+ };
+
+}
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/thread_only.hpp b/src/third_party/boost-1.60.0/boost/thread/thread_only.hpp
new file mode 100644
index 00000000000..0d0c07061f2
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/thread_only.hpp
@@ -0,0 +1,29 @@
+#ifndef BOOST_THREAD_THREAD_ONLY_HPP
+#define BOOST_THREAD_THREAD_ONLY_HPP
+
+// thread.hpp
+//
+// (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)
+
+#include <boost/thread/detail/platform.hpp>
+
+#if defined(BOOST_THREAD_PLATFORM_WIN32)
+#include <boost/thread/win32/thread_data.hpp>
+#elif defined(BOOST_THREAD_PLATFORM_PTHREAD)
+#include <boost/thread/pthread/thread_data.hpp>
+#else
+#error "Boost threads unavailable on this platform"
+#endif
+
+#include <boost/thread/detail/thread.hpp>
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+#include <boost/thread/detail/thread_interruption.hpp>
+#endif
+#include <boost/thread/v2/thread.hpp>
+
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/thread_pool.hpp b/src/third_party/boost-1.60.0/boost/thread/thread_pool.hpp
new file mode 100644
index 00000000000..4d2dcbea3a7
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/thread_pool.hpp
@@ -0,0 +1,15 @@
+// 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)
+//
+// 2013/09 Vicente J. Botet Escriba
+// Adapt to boost from CCIA C++11 implementation
+// first implementation of a simple pool thread using a vector of threads and a sync_queue.
+
+#ifndef BOOST_THREAD_THREAD_POOL_HPP
+#define BOOST_THREAD_THREAD_POOL_HPP
+
+#include <boost/thread/executors/basic_thread_pool.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/thread_time.hpp b/src/third_party/boost-1.60.0/boost/thread/thread_time.hpp
new file mode 100644
index 00000000000..ffdcf850f73
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/thread_time.hpp
@@ -0,0 +1,55 @@
+#ifndef BOOST_THREAD_TIME_HPP
+#define BOOST_THREAD_TIME_HPP
+// (C) Copyright 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/date_time/time_clock.hpp>
+#include <boost/date_time/microsec_time_clock.hpp>
+#include <boost/date_time/posix_time/posix_time_types.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ typedef boost::posix_time::ptime system_time;
+
+ inline system_time get_system_time()
+ {
+#if defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK)
+ return boost::date_time::microsec_clock<system_time>::universal_time();
+#else // defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK)
+ return boost::date_time::second_clock<system_time>::universal_time();
+#endif // defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK)
+ }
+
+ namespace detail
+ {
+ inline system_time get_system_time_sentinel()
+ {
+ return system_time(boost::posix_time::pos_infin);
+ }
+
+ inline unsigned long get_milliseconds_until(system_time const& target_time)
+ {
+ if(target_time.is_pos_infinity())
+ {
+ return ~(unsigned long)0;
+ }
+ system_time const now=get_system_time();
+ if(target_time<=now)
+ {
+ return 0;
+ }
+ return static_cast<unsigned long>((target_time-now).total_milliseconds()+1);
+ }
+
+ }
+
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/tss.hpp b/src/third_party/boost-1.60.0/boost/thread/tss.hpp
new file mode 100644
index 00000000000..d798bef558a
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/tss.hpp
@@ -0,0 +1,113 @@
+#ifndef BOOST_THREAD_TSS_HPP
+#define BOOST_THREAD_TSS_HPP
+// Distributed under the 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 2007-8 Anthony Williams
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/thread/detail/thread_heap_alloc.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ namespace detail
+ {
+ struct tss_cleanup_function
+ {
+ virtual ~tss_cleanup_function()
+ {}
+
+ virtual void operator()(void* data)=0;
+ };
+
+ BOOST_THREAD_DECL void set_tss_data(void const* key,boost::shared_ptr<tss_cleanup_function> func,void* tss_data,bool cleanup_existing);
+ BOOST_THREAD_DECL void* get_tss_data(void const* key);
+ }
+
+ template <typename T>
+ class thread_specific_ptr
+ {
+ private:
+ thread_specific_ptr(thread_specific_ptr&);
+ thread_specific_ptr& operator=(thread_specific_ptr&);
+
+ struct delete_data:
+ detail::tss_cleanup_function
+ {
+ void operator()(void* data)
+ {
+ delete static_cast<T*>(data);
+ }
+ };
+
+ struct run_custom_cleanup_function:
+ detail::tss_cleanup_function
+ {
+ void (*cleanup_function)(T*);
+
+ explicit run_custom_cleanup_function(void (*cleanup_function_)(T*)):
+ cleanup_function(cleanup_function_)
+ {}
+
+ void operator()(void* data)
+ {
+ cleanup_function(static_cast<T*>(data));
+ }
+ };
+
+
+ boost::shared_ptr<detail::tss_cleanup_function> cleanup;
+
+ public:
+ typedef T element_type;
+
+ thread_specific_ptr():
+ cleanup(detail::heap_new<delete_data>(),detail::do_heap_delete<delete_data>())
+ {}
+ explicit thread_specific_ptr(void (*func_)(T*))
+ {
+ if(func_)
+ {
+ cleanup.reset(detail::heap_new<run_custom_cleanup_function>(func_),detail::do_heap_delete<run_custom_cleanup_function>());
+ }
+ }
+ ~thread_specific_ptr()
+ {
+ detail::set_tss_data(this,boost::shared_ptr<detail::tss_cleanup_function>(),0,true);
+ }
+
+ T* get() const
+ {
+ return static_cast<T*>(detail::get_tss_data(this));
+ }
+ T* operator->() const
+ {
+ return get();
+ }
+ typename boost::detail::sp_dereference< T >::type operator*() const
+ {
+ return *get();
+ }
+ T* release()
+ {
+ T* const temp=get();
+ detail::set_tss_data(this,boost::shared_ptr<detail::tss_cleanup_function>(),0,false);
+ return temp;
+ }
+ void reset(T* new_value=0)
+ {
+ T* const current_value=get();
+ if(current_value!=new_value)
+ {
+ detail::set_tss_data(this,cleanup,new_value,true);
+ }
+ }
+ };
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/user_scheduler.hpp b/src/third_party/boost-1.60.0/boost/thread/user_scheduler.hpp
new file mode 100644
index 00000000000..c551d21710d
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/user_scheduler.hpp
@@ -0,0 +1,202 @@
+// 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)
+//
+// 2013/11 Vicente J. Botet Escriba
+// first implementation of a simple serial scheduler.
+
+#ifndef BOOST_THREAD_USER_SCHEDULER_HPP
+#define BOOST_THREAD_USER_SCHEDULER_HPP
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/detail/delete.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/concurrent_queues/sync_queue.hpp>
+#include <boost/thread/executors/work.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+
+ class user_scheduler
+ {
+ /// type-erasure to store the works to do
+ typedef thread_detail::work work;
+
+ /// the thread safe work queue
+ sync_queue<work > work_queue;
+
+ public:
+ /**
+ * Effects: try to execute one task.
+ * Returns: whether a task has been executed.
+ * Throws: whatever the current task constructor throws or the task() throws.
+ */
+ bool try_executing_one()
+ {
+ work task;
+ try
+ {
+ if (work_queue.try_pull(task) == queue_op_status::success)
+ {
+ task();
+ return true;
+ }
+ return false;
+ }
+ catch (std::exception& )
+ {
+ return false;
+ }
+ catch (...)
+ {
+ return false;
+ }
+ }
+ private:
+ /**
+ * Effects: schedule one task or yields
+ * Throws: whatever the current task constructor throws or the task() throws.
+ */
+ void schedule_one_or_yield()
+ {
+ if ( ! try_executing_one())
+ {
+ this_thread::yield();
+ }
+ }
+
+
+ /**
+ * The main loop of the worker thread
+ */
+ void worker_thread()
+ {
+ while (!closed())
+ {
+ schedule_one_or_yield();
+ }
+ while (try_executing_one())
+ {
+ }
+ }
+
+ public:
+ /// user_scheduler is not copyable.
+ BOOST_THREAD_NO_COPYABLE(user_scheduler)
+
+ /**
+ * \b Effects: creates a thread pool that runs closures using one of its closure-executing methods.
+ *
+ * \b Throws: Whatever exception is thrown while initializing the needed resources.
+ */
+ user_scheduler()
+ {
+ }
+ /**
+ * \b Effects: Destroys the thread pool.
+ *
+ * \b Synchronization: The completion of all the closures happen before the completion of the \c user_scheduler destructor.
+ */
+ ~user_scheduler()
+ {
+ // signal to all the worker thread that there will be no more submissions.
+ close();
+ }
+
+ /**
+ * loop
+ */
+ void loop() { worker_thread(); }
+ /**
+ * \b Effects: close the \c user_scheduler for submissions.
+ * The loop will work until there is no more closures to run.
+ */
+ void close()
+ {
+ work_queue.close();
+ }
+
+ /**
+ * \b Returns: whether the pool is closed for submissions.
+ */
+ bool closed()
+ {
+ return work_queue.closed();
+ }
+
+ /**
+ * \b Requires: \c Closure is a model of \c Callable(void()) and a model of \c CopyConstructible/MoveConstructible.
+ *
+ * \b Effects: The specified \c closure will be scheduled for execution at some point in the future.
+ * If invoked closure throws an exception the \c user_scheduler will call \c std::terminate, as is the case with threads.
+ *
+ * \b Synchronization: completion of \c closure on a particular thread happens before destruction of thread's thread local variables.
+ *
+ * \b Throws: \c sync_queue_is_closed if the thread pool is closed.
+ * Whatever exception that can be throw while storing the closure.
+ */
+
+#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ template <typename Closure>
+ void submit(Closure & closure)
+ {
+ work w ((closure));
+ work_queue.push(boost::move(w));
+ //work_queue.push(work(closure)); // todo check why this doesn't work
+ }
+#endif
+ void submit(void (*closure)())
+ {
+ work w ((closure));
+ work_queue.push(boost::move(w));
+ //work_queue.push(work(closure)); // todo check why this doesn't work
+ }
+
+ template <typename Closure>
+ void submit(BOOST_THREAD_RV_REF(Closure) closure)
+ {
+ work w =boost::move(closure);
+ work_queue.push(boost::move(w));
+ //work_queue.push(work(boost::move(closure))); // todo check why this doesn't work
+ }
+
+ /**
+ * \b Requires: This must be called from an scheduled task.
+ *
+ * \b Effects: reschedule functions until pred()
+ */
+ template <typename Pred>
+ bool reschedule_until(Pred const& pred)
+ {
+ do {
+ if ( ! try_executing_one())
+ {
+ return false;
+ }
+ } while (! pred());
+ return true;
+ }
+ /**
+ * run queued closures
+ */
+ void run_queued_closures()
+ {
+ sync_queue<work>::underlying_queue_type q = work_queue.underlying_queue();
+ while (q.empty())
+ {
+ work task = q.front();
+ q.pop_front();
+ task();
+ }
+ }
+
+ };
+
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/v2/shared_mutex.hpp b/src/third_party/boost-1.60.0/boost/thread/v2/shared_mutex.hpp
new file mode 100755
index 00000000000..5acab4d8cda
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/v2/shared_mutex.hpp
@@ -0,0 +1,1062 @@
+#ifndef BOOST_THREAD_V2_SHARED_MUTEX_HPP
+#define BOOST_THREAD_V2_SHARED_MUTEX_HPP
+
+// shared_mutex.hpp
+//
+// Copyright Howard Hinnant 2007-2010.
+// Copyright Vicente J. Botet Escriba 2012.
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/*
+<shared_mutex> synopsis
+
+namespace boost
+{
+namespace thread_v2
+{
+
+class shared_mutex
+{
+public:
+
+ shared_mutex();
+ ~shared_mutex();
+
+ shared_mutex(const shared_mutex&) = delete;
+ shared_mutex& operator=(const shared_mutex&) = delete;
+
+ // Exclusive ownership
+
+ void lock();
+ bool try_lock();
+ template <class Rep, class Period>
+ bool try_lock_for(const boost::chrono::duration<Rep, Period>& rel_time);
+ template <class Clock, class Duration>
+ bool
+ try_lock_until(
+ const boost::chrono::time_point<Clock, Duration>& abs_time);
+ void unlock();
+
+ // Shared ownership
+
+ void lock_shared();
+ bool try_lock_shared();
+ template <class Rep, class Period>
+ bool
+ try_lock_shared_for(const boost::chrono::duration<Rep, Period>& rel_time);
+ template <class Clock, class Duration>
+ bool
+ try_lock_shared_until(
+ const boost::chrono::time_point<Clock, Duration>& abs_time);
+ void unlock_shared();
+};
+
+class upgrade_mutex
+{
+public:
+
+ upgrade_mutex();
+ ~upgrade_mutex();
+
+ upgrade_mutex(const upgrade_mutex&) = delete;
+ upgrade_mutex& operator=(const upgrade_mutex&) = delete;
+
+ // Exclusive ownership
+
+ void lock();
+ bool try_lock();
+ template <class Rep, class Period>
+ bool try_lock_for(const boost::chrono::duration<Rep, Period>& rel_time);
+ template <class Clock, class Duration>
+ bool
+ try_lock_until(
+ const boost::chrono::time_point<Clock, Duration>& abs_time);
+ void unlock();
+
+ // Shared ownership
+
+ void lock_shared();
+ bool try_lock_shared();
+ template <class Rep, class Period>
+ bool
+ try_lock_shared_for(const boost::chrono::duration<Rep, Period>& rel_time);
+ template <class Clock, class Duration>
+ bool
+ try_lock_shared_until(
+ const boost::chrono::time_point<Clock, Duration>& abs_time);
+ void unlock_shared();
+
+ // Upgrade ownership
+
+ void lock_upgrade();
+ bool try_lock_upgrade();
+ template <class Rep, class Period>
+ bool
+ try_lock_upgrade_for(
+ const boost::chrono::duration<Rep, Period>& rel_time);
+ template <class Clock, class Duration>
+ bool
+ try_lock_upgrade_until(
+ const boost::chrono::time_point<Clock, Duration>& abs_time);
+ void unlock_upgrade();
+
+ // Shared <-> Exclusive
+
+ bool try_unlock_shared_and_lock();
+ template <class Rep, class Period>
+ bool
+ try_unlock_shared_and_lock_for(
+ const boost::chrono::duration<Rep, Period>& rel_time);
+ template <class Clock, class Duration>
+ bool
+ try_unlock_shared_and_lock_until(
+ const boost::chrono::time_point<Clock, Duration>& abs_time);
+ void unlock_and_lock_shared();
+
+ // Shared <-> Upgrade
+
+ bool try_unlock_shared_and_lock_upgrade();
+ template <class Rep, class Period>
+ bool
+ try_unlock_shared_and_lock_upgrade_for(
+ const boost::chrono::duration<Rep, Period>& rel_time);
+ template <class Clock, class Duration>
+ bool
+ try_unlock_shared_and_lock_upgrade_until(
+ const boost::chrono::time_point<Clock, Duration>& abs_time);
+ void unlock_upgrade_and_lock_shared();
+
+ // Upgrade <-> Exclusive
+
+ void unlock_upgrade_and_lock();
+ bool try_unlock_upgrade_and_lock();
+ template <class Rep, class Period>
+ bool
+ try_unlock_upgrade_and_lock_for(
+ const boost::chrono::duration<Rep, Period>& rel_time);
+ template <class Clock, class Duration>
+ bool
+ try_unlock_upgrade_and_lock_until(
+ const boost::chrono::time_point<Clock, Duration>& abs_time);
+ void unlock_and_lock_upgrade();
+};
+
+} // thread_v2
+} // boost
+
+ */
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/chrono.hpp>
+#include <climits>
+#include <boost/system/system_error.hpp>
+#define BOOST_THREAD_INLINE inline
+
+namespace boost {
+ namespace thread_v2 {
+
+ class shared_mutex
+ {
+ typedef ::boost::mutex mutex_t;
+ typedef ::boost::condition_variable cond_t;
+ typedef unsigned count_t;
+
+ mutex_t mut_;
+ cond_t gate1_;
+ cond_t gate2_;
+ count_t state_;
+
+ static const count_t write_entered_ = 1U << (sizeof(count_t)*CHAR_BIT - 1);
+ static const count_t n_readers_ = ~write_entered_;
+
+ public:
+ BOOST_THREAD_INLINE shared_mutex();
+ BOOST_THREAD_INLINE ~shared_mutex();
+
+#ifndef BOOST_NO_CXX11_DELETED_FUNCTIONS
+ shared_mutex(shared_mutex const&) = delete;
+ shared_mutex& operator=(shared_mutex const&) = delete;
+#else // BOOST_NO_CXX11_DELETED_FUNCTIONS
+ private:
+ shared_mutex(shared_mutex const&);
+ shared_mutex& operator=(shared_mutex const&);
+ public:
+#endif // BOOST_NO_CXX11_DELETED_FUNCTIONS
+
+ // Exclusive ownership
+
+ BOOST_THREAD_INLINE void lock();
+ BOOST_THREAD_INLINE bool try_lock();
+ template <class Rep, class Period>
+ bool try_lock_for(const boost::chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_lock_until(boost::chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool
+ try_lock_until(
+ const boost::chrono::time_point<Clock, Duration>& abs_time);
+ BOOST_THREAD_INLINE void unlock();
+
+
+ // Shared ownership
+
+ BOOST_THREAD_INLINE void lock_shared();
+ BOOST_THREAD_INLINE bool try_lock_shared();
+ template <class Rep, class Period>
+ bool
+ try_lock_shared_for(const boost::chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_lock_shared_until(boost::chrono::steady_clock::now() +
+ rel_time);
+ }
+ template <class Clock, class Duration>
+ bool
+ try_lock_shared_until(
+ const boost::chrono::time_point<Clock, Duration>& abs_time);
+ BOOST_THREAD_INLINE void unlock_shared();
+
+#if defined BOOST_THREAD_USES_DATETIME
+ bool timed_lock(system_time const& timeout);
+ template<typename TimeDuration>
+ bool timed_lock(TimeDuration const & relative_time)
+ {
+ return timed_lock(get_system_time()+relative_time);
+ }
+ bool timed_lock_shared(system_time const& timeout);
+ template<typename TimeDuration>
+ bool timed_lock_shared(TimeDuration const & relative_time)
+ {
+ return timed_lock_shared(get_system_time()+relative_time);
+ }
+#endif
+ };
+
+ template <class Clock, class Duration>
+ bool
+ shared_mutex::try_lock_until(
+ const boost::chrono::time_point<Clock, Duration>& abs_time)
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ if (state_ & write_entered_)
+ {
+ while (true)
+ {
+ boost::cv_status status = gate1_.wait_until(lk, abs_time);
+ if ((state_ & write_entered_) == 0)
+ break;
+ if (status == boost::cv_status::timeout)
+ return false;
+ }
+ }
+ state_ |= write_entered_;
+ if (state_ & n_readers_)
+ {
+ while (true)
+ {
+ boost::cv_status status = gate2_.wait_until(lk, abs_time);
+ if ((state_ & n_readers_) == 0)
+ break;
+ if (status == boost::cv_status::timeout)
+ {
+ state_ &= ~write_entered_;
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ template <class Clock, class Duration>
+ bool
+ shared_mutex::try_lock_shared_until(
+ const boost::chrono::time_point<Clock, Duration>& abs_time)
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ if ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
+ {
+ while (true)
+ {
+ boost::cv_status status = gate1_.wait_until(lk, abs_time);
+ if ((state_ & write_entered_) == 0 &&
+ (state_ & n_readers_) < n_readers_)
+ break;
+ if (status == boost::cv_status::timeout)
+ return false;
+ }
+ }
+ count_t num_readers = (state_ & n_readers_) + 1;
+ state_ &= ~n_readers_;
+ state_ |= num_readers;
+ return true;
+ }
+
+#if defined BOOST_THREAD_USES_DATETIME
+ bool shared_mutex::timed_lock(system_time const& abs_time)
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ if (state_ & write_entered_)
+ {
+ while (true)
+ {
+ bool status = gate1_.timed_wait(lk, abs_time);
+ if ((state_ & write_entered_) == 0)
+ break;
+ if (!status)
+ return false;
+ }
+ }
+ state_ |= write_entered_;
+ if (state_ & n_readers_)
+ {
+ while (true)
+ {
+ bool status = gate2_.timed_wait(lk, abs_time);
+ if ((state_ & n_readers_) == 0)
+ break;
+ if (!status)
+ {
+ state_ &= ~write_entered_;
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ bool shared_mutex::timed_lock_shared(system_time const& abs_time)
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ if (state_ & write_entered_)
+ {
+ while (true)
+ {
+ bool status = gate1_.timed_wait(lk, abs_time);
+ if ((state_ & write_entered_) == 0)
+ break;
+ if (!status )
+ return false;
+ }
+ }
+ state_ |= write_entered_;
+ if (state_ & n_readers_)
+ {
+ while (true)
+ {
+ bool status = gate2_.timed_wait(lk, abs_time);
+ if ((state_ & n_readers_) == 0)
+ break;
+ if (!status)
+ {
+ state_ &= ~write_entered_;
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+#endif
+ class upgrade_mutex
+ {
+ typedef boost::mutex mutex_t;
+ typedef boost::condition_variable cond_t;
+ typedef unsigned count_t;
+
+ mutex_t mut_;
+ cond_t gate1_;
+ cond_t gate2_;
+ count_t state_;
+
+ static const unsigned write_entered_ = 1U << (sizeof(count_t)*CHAR_BIT - 1);
+ static const unsigned upgradable_entered_ = write_entered_ >> 1;
+ static const unsigned n_readers_ = ~(write_entered_ | upgradable_entered_);
+
+ public:
+
+ BOOST_THREAD_INLINE upgrade_mutex();
+ BOOST_THREAD_INLINE ~upgrade_mutex();
+
+#ifndef BOOST_CXX11_NO_DELETED_FUNCTIONS
+ upgrade_mutex(const upgrade_mutex&) = delete;
+ upgrade_mutex& operator=(const upgrade_mutex&) = delete;
+#else // BOOST_CXX11_NO_DELETED_FUNCTIONS
+ private:
+ upgrade_mutex(const upgrade_mutex&);
+ upgrade_mutex& operator=(const upgrade_mutex&);
+ public:
+#endif // BOOST_CXX11_NO_DELETED_FUNCTIONS
+
+ // Exclusive ownership
+
+ BOOST_THREAD_INLINE void lock();
+ BOOST_THREAD_INLINE bool try_lock();
+ template <class Rep, class Period>
+ bool try_lock_for(const boost::chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_lock_until(boost::chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool
+ try_lock_until(
+ const boost::chrono::time_point<Clock, Duration>& abs_time);
+ BOOST_THREAD_INLINE void unlock();
+
+ // Shared ownership
+
+ BOOST_THREAD_INLINE void lock_shared();
+ BOOST_THREAD_INLINE bool try_lock_shared();
+ template <class Rep, class Period>
+ bool
+ try_lock_shared_for(const boost::chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_lock_shared_until(boost::chrono::steady_clock::now() +
+ rel_time);
+ }
+ template <class Clock, class Duration>
+ bool
+ try_lock_shared_until(
+ const boost::chrono::time_point<Clock, Duration>& abs_time);
+ BOOST_THREAD_INLINE void unlock_shared();
+
+ // Upgrade ownership
+
+ BOOST_THREAD_INLINE void lock_upgrade();
+ BOOST_THREAD_INLINE bool try_lock_upgrade();
+ template <class Rep, class Period>
+ bool
+ try_lock_upgrade_for(
+ const boost::chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_lock_upgrade_until(boost::chrono::steady_clock::now() +
+ rel_time);
+ }
+ template <class Clock, class Duration>
+ bool
+ try_lock_upgrade_until(
+ const boost::chrono::time_point<Clock, Duration>& abs_time);
+ BOOST_THREAD_INLINE void unlock_upgrade();
+
+ // Shared <-> Exclusive
+
+ BOOST_THREAD_INLINE bool try_unlock_shared_and_lock();
+ template <class Rep, class Period>
+ bool
+ try_unlock_shared_and_lock_for(
+ const boost::chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_unlock_shared_and_lock_until(
+ boost::chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool
+ try_unlock_shared_and_lock_until(
+ const boost::chrono::time_point<Clock, Duration>& abs_time);
+ BOOST_THREAD_INLINE void unlock_and_lock_shared();
+
+ // Shared <-> Upgrade
+
+ BOOST_THREAD_INLINE bool try_unlock_shared_and_lock_upgrade();
+ template <class Rep, class Period>
+ bool
+ try_unlock_shared_and_lock_upgrade_for(
+ const boost::chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_unlock_shared_and_lock_upgrade_until(
+ boost::chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool
+ try_unlock_shared_and_lock_upgrade_until(
+ const boost::chrono::time_point<Clock, Duration>& abs_time);
+ BOOST_THREAD_INLINE void unlock_upgrade_and_lock_shared();
+
+ // Upgrade <-> Exclusive
+
+ BOOST_THREAD_INLINE void unlock_upgrade_and_lock();
+ BOOST_THREAD_INLINE bool try_unlock_upgrade_and_lock();
+ template <class Rep, class Period>
+ bool
+ try_unlock_upgrade_and_lock_for(
+ const boost::chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_unlock_upgrade_and_lock_until(
+ boost::chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool
+ try_unlock_upgrade_and_lock_until(
+ const boost::chrono::time_point<Clock, Duration>& abs_time);
+ BOOST_THREAD_INLINE void unlock_and_lock_upgrade();
+
+#if defined BOOST_THREAD_USES_DATETIME
+ inline bool timed_lock(system_time const& abs_time);
+ template<typename TimeDuration>
+ bool timed_lock(TimeDuration const & relative_time)
+ {
+ return timed_lock(get_system_time()+relative_time);
+ }
+ inline bool timed_lock_shared(system_time const& abs_time);
+ template<typename TimeDuration>
+ bool timed_lock_shared(TimeDuration const & relative_time)
+ {
+ return timed_lock_shared(get_system_time()+relative_time);
+ }
+ inline bool timed_lock_upgrade(system_time const& abs_time);
+ template<typename TimeDuration>
+ bool timed_lock_upgrade(TimeDuration const & relative_time)
+ {
+ return timed_lock_upgrade(get_system_time()+relative_time);
+ }
+#endif
+
+ };
+
+ template <class Clock, class Duration>
+ bool
+ upgrade_mutex::try_lock_until(
+ const boost::chrono::time_point<Clock, Duration>& abs_time)
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ if (state_ & (write_entered_ | upgradable_entered_))
+ {
+ while (true)
+ {
+ boost::cv_status status = gate1_.wait_until(lk, abs_time);
+ if ((state_ & (write_entered_ | upgradable_entered_)) == 0)
+ break;
+ if (status == boost::cv_status::timeout)
+ return false;
+ }
+ }
+ state_ |= write_entered_;
+ if (state_ & n_readers_)
+ {
+ while (true)
+ {
+ boost::cv_status status = gate2_.wait_until(lk, abs_time);
+ if ((state_ & n_readers_) == 0)
+ break;
+ if (status == boost::cv_status::timeout)
+ {
+ state_ &= ~write_entered_;
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ template <class Clock, class Duration>
+ bool
+ upgrade_mutex::try_lock_shared_until(
+ const boost::chrono::time_point<Clock, Duration>& abs_time)
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ if ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
+ {
+ while (true)
+ {
+ boost::cv_status status = gate1_.wait_until(lk, abs_time);
+ if ((state_ & write_entered_) == 0 &&
+ (state_ & n_readers_) < n_readers_)
+ break;
+ if (status == boost::cv_status::timeout)
+ return false;
+ }
+ }
+ count_t num_readers = (state_ & n_readers_) + 1;
+ state_ &= ~n_readers_;
+ state_ |= num_readers;
+ return true;
+ }
+
+ template <class Clock, class Duration>
+ bool
+ upgrade_mutex::try_lock_upgrade_until(
+ const boost::chrono::time_point<Clock, Duration>& abs_time)
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ if ((state_ & (write_entered_ | upgradable_entered_)) ||
+ (state_ & n_readers_) == n_readers_)
+ {
+ while (true)
+ {
+ boost::cv_status status = gate1_.wait_until(lk, abs_time);
+ if ((state_ & (write_entered_ | upgradable_entered_)) == 0 &&
+ (state_ & n_readers_) < n_readers_)
+ break;
+ if (status == boost::cv_status::timeout)
+ return false;
+ }
+ }
+ count_t num_readers = (state_ & n_readers_) + 1;
+ state_ &= ~n_readers_;
+ state_ |= upgradable_entered_ | num_readers;
+ return true;
+ }
+
+#if defined BOOST_THREAD_USES_DATETIME
+ bool upgrade_mutex::timed_lock(system_time const& abs_time)
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ if (state_ & (write_entered_ | upgradable_entered_))
+ {
+ while (true)
+ {
+ bool status = gate1_.timed_wait(lk, abs_time);
+ if ((state_ & (write_entered_ | upgradable_entered_)) == 0)
+ break;
+ if (!status)
+ return false;
+ }
+ }
+ state_ |= write_entered_;
+ if (state_ & n_readers_)
+ {
+ while (true)
+ {
+ bool status = gate2_.timed_wait(lk, abs_time);
+ if ((state_ & n_readers_) == 0)
+ break;
+ if (!status)
+ {
+ state_ &= ~write_entered_;
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ bool upgrade_mutex::timed_lock_shared(system_time const& abs_time)
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ if ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
+ {
+ while (true)
+ {
+ bool status = gate1_.timed_wait(lk, abs_time);
+ if ((state_ & write_entered_) == 0 &&
+ (state_ & n_readers_) < n_readers_)
+ break;
+ if (!status)
+ return false;
+ }
+ }
+ count_t num_readers = (state_ & n_readers_) + 1;
+ state_ &= ~n_readers_;
+ state_ |= num_readers;
+ return true;
+ }
+ bool upgrade_mutex::timed_lock_upgrade(system_time const& abs_time)
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ if ((state_ & (write_entered_ | upgradable_entered_)) ||
+ (state_ & n_readers_) == n_readers_)
+ {
+ while (true)
+ {
+ bool status = gate1_.timed_wait(lk, abs_time);
+ if ((state_ & (write_entered_ | upgradable_entered_)) == 0 &&
+ (state_ & n_readers_) < n_readers_)
+ break;
+ if (!status)
+ return false;
+ }
+ }
+ count_t num_readers = (state_ & n_readers_) + 1;
+ state_ &= ~n_readers_;
+ state_ |= upgradable_entered_ | num_readers;
+ return true;
+ }
+
+#endif
+ template <class Clock, class Duration>
+ bool
+ upgrade_mutex::try_unlock_shared_and_lock_until(
+ const boost::chrono::time_point<Clock, Duration>& abs_time)
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ if (state_ != 1)
+ {
+ while (true)
+ {
+ boost::cv_status status = gate2_.wait_until(lk, abs_time);
+ if (state_ == 1)
+ break;
+ if (status == boost::cv_status::timeout)
+ return false;
+ }
+ }
+ state_ = write_entered_;
+ return true;
+ }
+
+ template <class Clock, class Duration>
+ bool
+ upgrade_mutex::try_unlock_shared_and_lock_upgrade_until(
+ const boost::chrono::time_point<Clock, Duration>& abs_time)
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ if ((state_ & (write_entered_ | upgradable_entered_)) != 0)
+ {
+ while (true)
+ {
+ boost::cv_status status = gate2_.wait_until(lk, abs_time);
+ if ((state_ & (write_entered_ | upgradable_entered_)) == 0)
+ break;
+ if (status == boost::cv_status::timeout)
+ return false;
+ }
+ }
+ state_ |= upgradable_entered_;
+ return true;
+ }
+
+ template <class Clock, class Duration>
+ bool
+ upgrade_mutex::try_unlock_upgrade_and_lock_until(
+ const boost::chrono::time_point<Clock, Duration>& abs_time)
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ if ((state_ & n_readers_) != 1)
+ {
+ while (true)
+ {
+ boost::cv_status status = gate2_.wait_until(lk, abs_time);
+ if ((state_ & n_readers_) == 1)
+ break;
+ if (status == boost::cv_status::timeout)
+ return false;
+ }
+ }
+ state_ = write_entered_;
+ return true;
+ }
+
+ //////
+ // shared_mutex
+
+ shared_mutex::shared_mutex()
+ : state_(0)
+ {
+ }
+
+ shared_mutex::~shared_mutex()
+ {
+ boost::lock_guard<mutex_t> _(mut_);
+ }
+
+ // Exclusive ownership
+
+ void
+ shared_mutex::lock()
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ while (state_ & write_entered_)
+ gate1_.wait(lk);
+ state_ |= write_entered_;
+ while (state_ & n_readers_)
+ gate2_.wait(lk);
+ }
+
+ bool
+ shared_mutex::try_lock()
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ if (state_ == 0)
+ {
+ state_ = write_entered_;
+ return true;
+ }
+ return false;
+ }
+
+ void
+ shared_mutex::unlock()
+ {
+ boost::lock_guard<mutex_t> _(mut_);
+ state_ = 0;
+ gate1_.notify_all();
+ }
+
+ // Shared ownership
+
+ void
+ shared_mutex::lock_shared()
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ while ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
+ gate1_.wait(lk);
+ count_t num_readers = (state_ & n_readers_) + 1;
+ state_ &= ~n_readers_;
+ state_ |= num_readers;
+ }
+
+ bool
+ shared_mutex::try_lock_shared()
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ count_t num_readers = state_ & n_readers_;
+ if (!(state_ & write_entered_) && num_readers != n_readers_)
+ {
+ ++num_readers;
+ state_ &= ~n_readers_;
+ state_ |= num_readers;
+ return true;
+ }
+ return false;
+ }
+
+ void
+ shared_mutex::unlock_shared()
+ {
+ boost::lock_guard<mutex_t> _(mut_);
+ count_t num_readers = (state_ & n_readers_) - 1;
+ state_ &= ~n_readers_;
+ state_ |= num_readers;
+ if (state_ & write_entered_)
+ {
+ if (num_readers == 0)
+ gate2_.notify_one();
+ }
+ else
+ {
+ if (num_readers == n_readers_ - 1)
+ gate1_.notify_one();
+ }
+ }
+
+ // upgrade_mutex
+
+ upgrade_mutex::upgrade_mutex()
+ : gate1_(),
+ gate2_(),
+ state_(0)
+ {
+ }
+
+ upgrade_mutex::~upgrade_mutex()
+ {
+ boost::lock_guard<mutex_t> _(mut_);
+ }
+
+ // Exclusive ownership
+
+ void
+ upgrade_mutex::lock()
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ while (state_ & (write_entered_ | upgradable_entered_))
+ gate1_.wait(lk);
+ state_ |= write_entered_;
+ while (state_ & n_readers_)
+ gate2_.wait(lk);
+ }
+
+ bool
+ upgrade_mutex::try_lock()
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ if (state_ == 0)
+ {
+ state_ = write_entered_;
+ return true;
+ }
+ return false;
+ }
+
+ void
+ upgrade_mutex::unlock()
+ {
+ boost::lock_guard<mutex_t> _(mut_);
+ state_ = 0;
+ gate1_.notify_all();
+ }
+
+ // Shared ownership
+
+ void
+ upgrade_mutex::lock_shared()
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ while ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
+ gate1_.wait(lk);
+ count_t num_readers = (state_ & n_readers_) + 1;
+ state_ &= ~n_readers_;
+ state_ |= num_readers;
+ }
+
+ bool
+ upgrade_mutex::try_lock_shared()
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ count_t num_readers = state_ & n_readers_;
+ if (!(state_ & write_entered_) && num_readers != n_readers_)
+ {
+ ++num_readers;
+ state_ &= ~n_readers_;
+ state_ |= num_readers;
+ return true;
+ }
+ return false;
+ }
+
+ void
+ upgrade_mutex::unlock_shared()
+ {
+ boost::lock_guard<mutex_t> _(mut_);
+ count_t num_readers = (state_ & n_readers_) - 1;
+ state_ &= ~n_readers_;
+ state_ |= num_readers;
+ if (state_ & write_entered_)
+ {
+ if (num_readers == 0)
+ gate2_.notify_one();
+ }
+ else
+ {
+ if (num_readers == n_readers_ - 1)
+ gate1_.notify_one();
+ }
+ }
+
+ // Upgrade ownership
+
+ void
+ upgrade_mutex::lock_upgrade()
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ while ((state_ & (write_entered_ | upgradable_entered_)) ||
+ (state_ & n_readers_) == n_readers_)
+ gate1_.wait(lk);
+ count_t num_readers = (state_ & n_readers_) + 1;
+ state_ &= ~n_readers_;
+ state_ |= upgradable_entered_ | num_readers;
+ }
+
+ bool
+ upgrade_mutex::try_lock_upgrade()
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ count_t num_readers = state_ & n_readers_;
+ if (!(state_ & (write_entered_ | upgradable_entered_))
+ && num_readers != n_readers_)
+ {
+ ++num_readers;
+ state_ &= ~n_readers_;
+ state_ |= upgradable_entered_ | num_readers;
+ return true;
+ }
+ return false;
+ }
+
+ void
+ upgrade_mutex::unlock_upgrade()
+ {
+ {
+ boost::lock_guard<mutex_t> _(mut_);
+ count_t num_readers = (state_ & n_readers_) - 1;
+ state_ &= ~(upgradable_entered_ | n_readers_);
+ state_ |= num_readers;
+ }
+ gate1_.notify_all();
+ }
+
+ // Shared <-> Exclusive
+
+ bool
+ upgrade_mutex::try_unlock_shared_and_lock()
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ if (state_ == 1)
+ {
+ state_ = write_entered_;
+ return true;
+ }
+ return false;
+ }
+
+ void
+ upgrade_mutex::unlock_and_lock_shared()
+ {
+ {
+ boost::lock_guard<mutex_t> _(mut_);
+ state_ = 1;
+ }
+ gate1_.notify_all();
+ }
+
+ // Shared <-> Upgrade
+
+ bool
+ upgrade_mutex::try_unlock_shared_and_lock_upgrade()
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ if (!(state_ & (write_entered_ | upgradable_entered_)))
+ {
+ state_ |= upgradable_entered_;
+ return true;
+ }
+ return false;
+ }
+
+ void
+ upgrade_mutex::unlock_upgrade_and_lock_shared()
+ {
+ {
+ boost::lock_guard<mutex_t> _(mut_);
+ state_ &= ~upgradable_entered_;
+ }
+ gate1_.notify_all();
+ }
+
+ // Upgrade <-> Exclusive
+
+ void
+ upgrade_mutex::unlock_upgrade_and_lock()
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ count_t num_readers = (state_ & n_readers_) - 1;
+ state_ &= ~(upgradable_entered_ | n_readers_);
+ state_ |= write_entered_ | num_readers;
+ while (state_ & n_readers_)
+ gate2_.wait(lk);
+ }
+
+ bool
+ upgrade_mutex::try_unlock_upgrade_and_lock()
+ {
+ boost::unique_lock<mutex_t> lk(mut_);
+ if (state_ == (upgradable_entered_ | 1))
+ {
+ state_ = write_entered_;
+ return true;
+ }
+ return false;
+ }
+
+ void
+ upgrade_mutex::unlock_and_lock_upgrade()
+ {
+ {
+ boost::lock_guard<mutex_t> _(mut_);
+ state_ = upgradable_entered_ | 1;
+ }
+ gate1_.notify_all();
+ }
+
+ } // thread_v2
+} // boost
+
+namespace boost {
+ //using thread_v2::shared_mutex;
+ using thread_v2::upgrade_mutex;
+ typedef thread_v2::upgrade_mutex shared_mutex;
+}
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/v2/thread.hpp b/src/third_party/boost-1.60.0/boost/thread/v2/thread.hpp
new file mode 100644
index 00000000000..53560610e23
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/v2/thread.hpp
@@ -0,0 +1,155 @@
+// Distributed under the 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 2011 Vicente J. Botet Escriba
+
+#ifndef BOOST_THREAD_V2_THREAD_HPP
+#define BOOST_THREAD_V2_THREAD_HPP
+
+#include <boost/thread/detail/config.hpp>
+#ifdef BOOST_THREAD_USES_CHRONO
+#include <boost/chrono/system_clocks.hpp>
+#include <boost/chrono/ceil.hpp>
+#endif
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/lock_types.hpp>
+
+namespace boost
+{
+ namespace this_thread
+ {
+ namespace no_interruption_point
+ {
+#ifdef BOOST_THREAD_USES_CHRONO
+
+ template <class Clock, class Duration>
+ void sleep_until(const chrono::time_point<Clock, Duration>& t)
+ {
+ using namespace chrono;
+ mutex mut;
+ condition_variable cv;
+ unique_lock<mutex> lk(mut);
+ while (Clock::now() < t)
+ cv.wait_until(lk, t);
+ }
+
+#ifdef BOOST_THREAD_SLEEP_FOR_IS_STEADY
+
+ template <class Rep, class Period>
+ void sleep_for(const chrono::duration<Rep, Period>& d)
+ {
+ using namespace chrono;
+ if (d > duration<Rep, Period>::zero())
+ {
+ duration<long double> Max = nanoseconds::max BOOST_PREVENT_MACRO_SUBSTITUTION ();
+ nanoseconds ns;
+ if (d < Max)
+ {
+ ns = duration_cast<nanoseconds>(d);
+ if (ns < d)
+ ++ns;
+ }
+ else
+ ns = nanoseconds:: max BOOST_PREVENT_MACRO_SUBSTITUTION ();
+ sleep_for(ns);
+ }
+ }
+
+ template <class Duration>
+ inline BOOST_SYMBOL_VISIBLE
+ void sleep_until(const chrono::time_point<chrono::steady_clock, Duration>& t)
+ {
+ using namespace chrono;
+ sleep_for(t - steady_clock::now());
+ }
+#else
+ template <class Rep, class Period>
+ void sleep_for(const chrono::duration<Rep, Period>& d)
+ {
+ using namespace chrono;
+ if (d > duration<Rep, Period>::zero())
+ {
+ steady_clock::time_point c_timeout = steady_clock::now() + ceil<nanoseconds>(d);
+ sleep_until(c_timeout);
+ }
+ }
+
+#endif
+
+#endif
+ }
+#ifdef BOOST_THREAD_USES_CHRONO
+
+ template <class Clock, class Duration>
+ void sleep_until(const chrono::time_point<Clock, Duration>& t)
+ {
+ using namespace chrono;
+ mutex mut;
+ condition_variable cv;
+ unique_lock<mutex> lk(mut);
+ while (Clock::now() < t)
+ cv.wait_until(lk, t);
+ }
+
+#if defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC && defined BOOST_CHRONO_HAS_CLOCK_STEADY
+ template <class Rep, class Period>
+ void sleep_for(const chrono::duration<Rep, Period>& d)
+ {
+ using namespace chrono;
+ if (d > duration<Rep, Period>::zero())
+ {
+ steady_clock::time_point c_timeout = steady_clock::now() + ceil<nanoseconds>(d);
+ sleep_until(c_timeout);
+ }
+ }
+
+#elif defined BOOST_THREAD_SLEEP_FOR_IS_STEADY
+
+ template <class Rep, class Period>
+ void sleep_for(const chrono::duration<Rep, Period>& d)
+ {
+ using namespace chrono;
+ if (d > duration<Rep, Period>::zero())
+ {
+ duration<long double> Max = nanoseconds::max BOOST_PREVENT_MACRO_SUBSTITUTION ();
+ nanoseconds ns;
+ if (d < Max)
+ {
+ ns = duration_cast<nanoseconds>(d);
+ if (ns < d)
+ ++ns;
+ }
+ else
+ ns = nanoseconds:: max BOOST_PREVENT_MACRO_SUBSTITUTION ();
+ sleep_for(ns);
+ }
+ }
+
+ template <class Duration>
+ inline BOOST_SYMBOL_VISIBLE
+ void sleep_until(const chrono::time_point<chrono::steady_clock, Duration>& t)
+ {
+ using namespace chrono;
+ sleep_for(t - steady_clock::now());
+ }
+#else
+ template <class Rep, class Period>
+ void sleep_for(const chrono::duration<Rep, Period>& d)
+ {
+ using namespace chrono;
+ if (d > duration<Rep, Period>::zero())
+ {
+ //system_clock::time_point c_timeout = time_point_cast<system_clock::duration>(system_clock::now() + ceil<nanoseconds>(d));
+ system_clock::time_point c_timeout = system_clock::now() + ceil<system_clock::duration>(d);
+ sleep_until(c_timeout);
+ }
+ }
+
+#endif
+
+#endif
+ }
+}
+
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/win32/basic_recursive_mutex.hpp b/src/third_party/boost-1.60.0/boost/thread/win32/basic_recursive_mutex.hpp
new file mode 100644
index 00000000000..cfdfa043a3b
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/win32/basic_recursive_mutex.hpp
@@ -0,0 +1,164 @@
+#ifndef BOOST_BASIC_RECURSIVE_MUTEX_WIN32_HPP
+#define BOOST_BASIC_RECURSIVE_MUTEX_WIN32_HPP
+
+// basic_recursive_mutex.hpp
+//
+// (C) Copyright 2006-8 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)
+
+#include <boost/thread/win32/thread_primitives.hpp>
+#include <boost/thread/win32/basic_timed_mutex.hpp>
+#ifdef BOOST_THREAD_USES_CHRONO
+#include <boost/chrono/system_clocks.hpp>
+#include <boost/chrono/ceil.hpp>
+#endif
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ namespace detail
+ {
+ template<typename underlying_mutex_type>
+ struct basic_recursive_mutex_impl
+ {
+ long recursion_count;
+ long locking_thread_id;
+ underlying_mutex_type mutex;
+
+ void initialize()
+ {
+ recursion_count=0;
+ locking_thread_id=0;
+ mutex.initialize();
+ }
+
+ void destroy()
+ {
+ mutex.destroy();
+ }
+
+ bool try_lock() BOOST_NOEXCEPT
+ {
+ long const current_thread_id=win32::GetCurrentThreadId();
+ return try_recursive_lock(current_thread_id) || try_basic_lock(current_thread_id);
+ }
+
+ void lock()
+ {
+ long const current_thread_id=win32::GetCurrentThreadId();
+ if(!try_recursive_lock(current_thread_id))
+ {
+ mutex.lock();
+ BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id);
+ recursion_count=1;
+ }
+ }
+#if defined BOOST_THREAD_USES_DATETIME
+ bool timed_lock(::boost::system_time const& target)
+ {
+ long const current_thread_id=win32::GetCurrentThreadId();
+ return try_recursive_lock(current_thread_id) || try_timed_lock(current_thread_id,target);
+ }
+ template<typename Duration>
+ bool timed_lock(Duration const& timeout)
+ {
+ return timed_lock(get_system_time()+timeout);
+ }
+#endif
+
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
+ {
+ long const current_thread_id=win32::GetCurrentThreadId();
+ return try_recursive_lock(current_thread_id) || try_timed_lock_for(current_thread_id,rel_time);
+ }
+ template <class Clock, class Duration>
+ bool try_lock_until(const chrono::time_point<Clock, Duration>& t)
+ {
+ long const current_thread_id=win32::GetCurrentThreadId();
+ return try_recursive_lock(current_thread_id) || try_timed_lock_until(current_thread_id,t);
+ }
+#endif
+ void unlock()
+ {
+ if(!--recursion_count)
+ {
+ BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,0);
+ mutex.unlock();
+ }
+ }
+
+ private:
+ bool try_recursive_lock(long current_thread_id) BOOST_NOEXCEPT
+ {
+ if(::boost::detail::interlocked_read_acquire(&locking_thread_id)==current_thread_id)
+ {
+ ++recursion_count;
+ return true;
+ }
+ return false;
+ }
+
+ bool try_basic_lock(long current_thread_id) BOOST_NOEXCEPT
+ {
+ if(mutex.try_lock())
+ {
+ BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id);
+ recursion_count=1;
+ return true;
+ }
+ return false;
+ }
+
+#if defined BOOST_THREAD_USES_DATETIME
+ bool try_timed_lock(long current_thread_id,::boost::system_time const& target)
+ {
+ if(mutex.timed_lock(target))
+ {
+ BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id);
+ recursion_count=1;
+ return true;
+ }
+ return false;
+ }
+#endif
+ template <typename TP>
+ bool try_timed_lock_until(long current_thread_id,TP const& target)
+ {
+ if(mutex.try_lock_until(target))
+ {
+ BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id);
+ recursion_count=1;
+ return true;
+ }
+ return false;
+ }
+ template <typename D>
+ bool try_timed_lock_for(long current_thread_id,D const& target)
+ {
+ if(mutex.try_lock_for(target))
+ {
+ BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id);
+ recursion_count=1;
+ return true;
+ }
+ return false;
+ }
+ };
+
+ typedef basic_recursive_mutex_impl<basic_timed_mutex> basic_recursive_mutex;
+ typedef basic_recursive_mutex_impl<basic_timed_mutex> basic_recursive_timed_mutex;
+ }
+}
+
+#define BOOST_BASIC_RECURSIVE_MUTEX_INITIALIZER {0}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/win32/basic_timed_mutex.hpp b/src/third_party/boost-1.60.0/boost/thread/win32/basic_timed_mutex.hpp
new file mode 100644
index 00000000000..d20c6589e69
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/win32/basic_timed_mutex.hpp
@@ -0,0 +1,279 @@
+#ifndef BOOST_BASIC_TIMED_MUTEX_WIN32_HPP
+#define BOOST_BASIC_TIMED_MUTEX_WIN32_HPP
+
+// basic_timed_mutex_win32.hpp
+//
+// (C) Copyright 2006-8 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)
+
+#include <boost/assert.hpp>
+#include <boost/thread/win32/thread_primitives.hpp>
+#include <boost/thread/win32/interlocked_read.hpp>
+#include <boost/thread/thread_time.hpp>
+#if defined BOOST_THREAD_USES_DATETIME
+#include <boost/thread/xtime.hpp>
+#endif
+#include <boost/detail/interlocked.hpp>
+#ifdef BOOST_THREAD_USES_CHRONO
+#include <boost/chrono/system_clocks.hpp>
+#include <boost/chrono/ceil.hpp>
+#endif
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ namespace detail
+ {
+ struct basic_timed_mutex
+ {
+ BOOST_STATIC_CONSTANT(unsigned char,lock_flag_bit=31);
+ BOOST_STATIC_CONSTANT(unsigned char,event_set_flag_bit=30);
+ BOOST_STATIC_CONSTANT(long,lock_flag_value=1<<lock_flag_bit);
+ BOOST_STATIC_CONSTANT(long,event_set_flag_value=1<<event_set_flag_bit);
+ long active_count;
+ void* event;
+
+ void initialize()
+ {
+ active_count=0;
+ event=0;
+ }
+
+ void destroy()
+ {
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4312)
+#endif
+ void* const old_event=BOOST_INTERLOCKED_EXCHANGE_POINTER(&event,0);
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+ if(old_event)
+ {
+ win32::CloseHandle(old_event);
+ }
+ }
+
+
+ bool try_lock() BOOST_NOEXCEPT
+ {
+ return !win32::interlocked_bit_test_and_set(&active_count,lock_flag_bit);
+ }
+
+ void lock()
+ {
+ if(try_lock())
+ {
+ return;
+ }
+ long old_count=active_count;
+ mark_waiting_and_try_lock(old_count);
+
+ if(old_count&lock_flag_value)
+ {
+ bool lock_acquired=false;
+ void* const sem=get_event();
+
+ do
+ {
+ unsigned const retval(win32::WaitForSingleObjectEx(sem, ::boost::detail::win32::infinite,0));
+ BOOST_VERIFY(0 == retval || ::boost::detail::win32::wait_abandoned == retval);
+// BOOST_VERIFY(win32::WaitForSingleObject(
+// sem,::boost::detail::win32::infinite)==0);
+ clear_waiting_and_try_lock(old_count);
+ lock_acquired=!(old_count&lock_flag_value);
+ }
+ while(!lock_acquired);
+ }
+ }
+ void mark_waiting_and_try_lock(long& old_count)
+ {
+ for(;;)
+ {
+ bool const was_locked=(old_count&lock_flag_value) ? true : false;
+ long const new_count=was_locked?(old_count+1):(old_count|lock_flag_value);
+ long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&active_count,new_count,old_count);
+ if(current==old_count)
+ {
+ if(was_locked)
+ old_count=new_count;
+ break;
+ }
+ old_count=current;
+ }
+ }
+
+ void clear_waiting_and_try_lock(long& old_count)
+ {
+ old_count&=~lock_flag_value;
+ old_count|=event_set_flag_value;
+ for(;;)
+ {
+ long const new_count=((old_count&lock_flag_value)?old_count:((old_count-1)|lock_flag_value))&~event_set_flag_value;
+ long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&active_count,new_count,old_count);
+ if(current==old_count)
+ {
+ break;
+ }
+ old_count=current;
+ }
+ }
+
+
+#if defined BOOST_THREAD_USES_DATETIME
+ bool timed_lock(::boost::system_time const& wait_until)
+ {
+ if(try_lock())
+ {
+ return true;
+ }
+ long old_count=active_count;
+ mark_waiting_and_try_lock(old_count);
+
+ if(old_count&lock_flag_value)
+ {
+ bool lock_acquired=false;
+ void* const sem=get_event();
+
+ do
+ {
+ if(win32::WaitForSingleObjectEx(sem,::boost::detail::get_milliseconds_until(wait_until),0)!=0)
+ {
+ BOOST_INTERLOCKED_DECREMENT(&active_count);
+ return false;
+ }
+ clear_waiting_and_try_lock(old_count);
+ lock_acquired=!(old_count&lock_flag_value);
+ }
+ while(!lock_acquired);
+ }
+ return true;
+ }
+
+ template<typename Duration>
+ bool timed_lock(Duration const& timeout)
+ {
+ return timed_lock(get_system_time()+timeout);
+ }
+
+ bool timed_lock(boost::xtime const& timeout)
+ {
+ return timed_lock(system_time(timeout));
+ }
+#endif
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_lock_until(chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool try_lock_until(const chrono::time_point<Clock, Duration>& t)
+ {
+ using namespace chrono;
+ system_clock::time_point s_now = system_clock::now();
+ typename Clock::time_point c_now = Clock::now();
+ return try_lock_until(s_now + ceil<system_clock::duration>(t - c_now));
+ }
+ template <class Duration>
+ bool try_lock_until(const chrono::time_point<chrono::system_clock, Duration>& t)
+ {
+ using namespace chrono;
+ typedef time_point<chrono::system_clock, chrono::system_clock::duration> sys_tmpt;
+ return try_lock_until(sys_tmpt(chrono::ceil<chrono::system_clock::duration>(t.time_since_epoch())));
+ }
+ bool try_lock_until(const chrono::time_point<chrono::system_clock, chrono::system_clock::duration>& tp)
+ {
+ if(try_lock())
+ {
+ return true;
+ }
+ long old_count=active_count;
+ mark_waiting_and_try_lock(old_count);
+
+ if(old_count&lock_flag_value)
+ {
+ bool lock_acquired=false;
+ void* const sem=get_event();
+
+ do
+ {
+ chrono::time_point<chrono::system_clock, chrono::system_clock::duration> now = chrono::system_clock::now();
+ if (tp<=now) {
+ BOOST_INTERLOCKED_DECREMENT(&active_count);
+ return false;
+ }
+ chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-now);
+
+ if(win32::WaitForSingleObjectEx(sem,static_cast<unsigned long>(rel_time.count()),0)!=0)
+ {
+ BOOST_INTERLOCKED_DECREMENT(&active_count);
+ return false;
+ }
+ clear_waiting_and_try_lock(old_count);
+ lock_acquired=!(old_count&lock_flag_value);
+ }
+ while(!lock_acquired);
+ }
+ return true;
+ }
+#endif
+
+ void unlock()
+ {
+ long const offset=lock_flag_value;
+ long const old_count=BOOST_INTERLOCKED_EXCHANGE_ADD(&active_count,lock_flag_value);
+ if(!(old_count&event_set_flag_value) && (old_count>offset))
+ {
+ if(!win32::interlocked_bit_test_and_set(&active_count,event_set_flag_bit))
+ {
+ win32::SetEvent(get_event());
+ }
+ }
+ }
+
+ private:
+ void* get_event()
+ {
+ void* current_event=::boost::detail::interlocked_read_acquire(&event);
+
+ if(!current_event)
+ {
+ void* const new_event=win32::create_anonymous_event(win32::auto_reset_event,win32::event_initially_reset);
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4311)
+#pragma warning(disable:4312)
+#endif
+ void* const old_event=BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(&event,new_event,0);
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+ if(old_event!=0)
+ {
+ win32::CloseHandle(new_event);
+ return old_event;
+ }
+ else
+ {
+ return new_event;
+ }
+ }
+ return current_event;
+ }
+
+ };
+
+ }
+}
+
+#define BOOST_BASIC_TIMED_MUTEX_INITIALIZER {0}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/win32/condition_variable.hpp b/src/third_party/boost-1.60.0/boost/thread/win32/condition_variable.hpp
new file mode 100644
index 00000000000..23e9e444840
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/win32/condition_variable.hpp
@@ -0,0 +1,567 @@
+#ifndef BOOST_THREAD_CONDITION_VARIABLE_WIN32_HPP
+#define BOOST_THREAD_CONDITION_VARIABLE_WIN32_HPP
+// Distributed under the 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 2007-8 Anthony Williams
+// (C) Copyright 2011-2012 Vicente J. Botet Escriba
+
+#include <boost/thread/win32/thread_primitives.hpp>
+#include <boost/thread/win32/thread_data.hpp>
+#include <boost/thread/win32/thread_data.hpp>
+#include <boost/thread/win32/interlocked_read.hpp>
+#include <boost/thread/cv_status.hpp>
+#if defined BOOST_THREAD_USES_DATETIME
+#include <boost/thread/xtime.hpp>
+#endif
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread_time.hpp>
+#include <boost/thread/lock_guard.hpp>
+#include <boost/thread/lock_types.hpp>
+
+#include <boost/assert.hpp>
+#include <boost/intrusive_ptr.hpp>
+
+#ifdef BOOST_THREAD_USES_CHRONO
+#include <boost/chrono/system_clocks.hpp>
+#include <boost/chrono/ceil.hpp>
+#endif
+
+#include <limits.h>
+#include <algorithm>
+#include <vector>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ namespace detail
+ {
+ class basic_cv_list_entry;
+ void intrusive_ptr_add_ref(basic_cv_list_entry * p);
+ void intrusive_ptr_release(basic_cv_list_entry * p);
+
+ class basic_cv_list_entry
+ {
+ private:
+ detail::win32::handle_manager semaphore;
+ detail::win32::handle_manager wake_sem;
+ long waiters;
+ bool notified;
+ long references;
+
+ public:
+ BOOST_THREAD_NO_COPYABLE(basic_cv_list_entry)
+ explicit basic_cv_list_entry(detail::win32::handle_manager const& wake_sem_):
+ semaphore(detail::win32::create_anonymous_semaphore(0,LONG_MAX)),
+ wake_sem(wake_sem_.duplicate()),
+ waiters(1),notified(false),references(0)
+ {}
+
+ static bool no_waiters(boost::intrusive_ptr<basic_cv_list_entry> const& entry)
+ {
+ return !detail::interlocked_read_acquire(&entry->waiters);
+ }
+
+ void add_waiter()
+ {
+ BOOST_INTERLOCKED_INCREMENT(&waiters);
+ }
+
+ void remove_waiter()
+ {
+ BOOST_INTERLOCKED_DECREMENT(&waiters);
+ }
+
+ void release(unsigned count_to_release)
+ {
+ notified=true;
+ detail::win32::ReleaseSemaphore(semaphore,count_to_release,0);
+ }
+
+ void release_waiters()
+ {
+ release(detail::interlocked_read_acquire(&waiters));
+ }
+
+ bool is_notified() const
+ {
+ return notified;
+ }
+
+ bool wait(timeout abs_time)
+ {
+ return this_thread::interruptible_wait(semaphore,abs_time);
+ }
+
+ bool woken()
+ {
+ unsigned long const woken_result=detail::win32::WaitForSingleObjectEx(wake_sem,0,0);
+ BOOST_ASSERT((woken_result==detail::win32::timeout) || (woken_result==0));
+ return woken_result==0;
+ }
+
+ friend void intrusive_ptr_add_ref(basic_cv_list_entry * p);
+ friend void intrusive_ptr_release(basic_cv_list_entry * p);
+ };
+
+ inline void intrusive_ptr_add_ref(basic_cv_list_entry * p)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&p->references);
+ }
+
+ inline void intrusive_ptr_release(basic_cv_list_entry * p)
+ {
+ if(!BOOST_INTERLOCKED_DECREMENT(&p->references))
+ {
+ delete p;
+ }
+ }
+
+ class basic_condition_variable
+ {
+ boost::mutex internal_mutex;
+ long total_count;
+ unsigned active_generation_count;
+
+ typedef basic_cv_list_entry list_entry;
+
+ typedef boost::intrusive_ptr<list_entry> entry_ptr;
+ typedef std::vector<entry_ptr> generation_list;
+
+ generation_list generations;
+ detail::win32::handle_manager wake_sem;
+
+ void wake_waiters(long count_to_wake)
+ {
+ detail::interlocked_write_release(&total_count,total_count-count_to_wake);
+ detail::win32::ReleaseSemaphore(wake_sem,count_to_wake,0);
+ }
+
+ template<typename lock_type>
+ struct relocker
+ {
+ BOOST_THREAD_NO_COPYABLE(relocker)
+ lock_type& lock;
+ bool unlocked;
+
+ relocker(lock_type& lock_):
+ lock(lock_),unlocked(false)
+ {}
+ void unlock()
+ {
+ lock.unlock();
+ unlocked=true;
+ }
+ ~relocker()
+ {
+ if(unlocked)
+ {
+ lock.lock();
+ }
+
+ }
+ };
+
+
+ entry_ptr get_wait_entry()
+ {
+ boost::lock_guard<boost::mutex> internal_lock(internal_mutex);
+
+ if(!wake_sem)
+ {
+ wake_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
+ BOOST_ASSERT(wake_sem);
+ }
+
+ detail::interlocked_write_release(&total_count,total_count+1);
+ if(generations.empty() || generations.back()->is_notified())
+ {
+ entry_ptr new_entry(new list_entry(wake_sem));
+ generations.push_back(new_entry);
+ return new_entry;
+ }
+ else
+ {
+ generations.back()->add_waiter();
+ return generations.back();
+ }
+ }
+
+ struct entry_manager
+ {
+ entry_ptr const entry;
+ boost::mutex& internal_mutex;
+
+ BOOST_THREAD_NO_COPYABLE(entry_manager)
+ entry_manager(entry_ptr const& entry_, boost::mutex& mutex_):
+ entry(entry_), internal_mutex(mutex_)
+ {}
+
+ ~entry_manager()
+ {
+ boost::lock_guard<boost::mutex> internal_lock(internal_mutex);
+ entry->remove_waiter();
+ }
+
+ list_entry* operator->()
+ {
+ return entry.get();
+ }
+ };
+
+
+ protected:
+ template<typename lock_type>
+ bool do_wait(lock_type& lock,timeout abs_time)
+ {
+ relocker<lock_type> locker(lock);
+
+ entry_manager entry(get_wait_entry(), internal_mutex);
+
+ locker.unlock();
+
+ bool woken=false;
+ while(!woken)
+ {
+ if(!entry->wait(abs_time))
+ {
+ return false;
+ }
+
+ woken=entry->woken();
+ }
+ return woken;
+ }
+
+ template<typename lock_type,typename predicate_type>
+ bool do_wait(lock_type& m,timeout const& abs_time,predicate_type pred)
+ {
+ while (!pred())
+ {
+ if(!do_wait(m, abs_time))
+ return pred();
+ }
+ return true;
+ }
+
+ basic_condition_variable(const basic_condition_variable& other);
+ basic_condition_variable& operator=(const basic_condition_variable& other);
+
+ public:
+ basic_condition_variable():
+ total_count(0),active_generation_count(0),wake_sem(0)
+ {}
+
+ ~basic_condition_variable()
+ {}
+
+ void notify_one() BOOST_NOEXCEPT
+ {
+ if(detail::interlocked_read_acquire(&total_count))
+ {
+ boost::lock_guard<boost::mutex> internal_lock(internal_mutex);
+ if(!total_count)
+ {
+ return;
+ }
+ wake_waiters(1);
+
+ for(generation_list::iterator it=generations.begin(),
+ end=generations.end();
+ it!=end;++it)
+ {
+ (*it)->release(1);
+ }
+ generations.erase(std::remove_if(generations.begin(),generations.end(),&basic_cv_list_entry::no_waiters),generations.end());
+ }
+ }
+
+ void notify_all() BOOST_NOEXCEPT
+ {
+ if(detail::interlocked_read_acquire(&total_count))
+ {
+ boost::lock_guard<boost::mutex> internal_lock(internal_mutex);
+ if(!total_count)
+ {
+ return;
+ }
+ wake_waiters(total_count);
+ for(generation_list::iterator it=generations.begin(),
+ end=generations.end();
+ it!=end;++it)
+ {
+ (*it)->release_waiters();
+ }
+ generations.clear();
+ wake_sem=detail::win32::handle(0);
+ }
+ }
+
+ };
+ }
+
+ class condition_variable:
+ private detail::basic_condition_variable
+ {
+ public:
+ BOOST_THREAD_NO_COPYABLE(condition_variable)
+ condition_variable()
+ {}
+
+ using detail::basic_condition_variable::notify_one;
+ using detail::basic_condition_variable::notify_all;
+
+ void wait(unique_lock<mutex>& m)
+ {
+ do_wait(m,detail::timeout::sentinel());
+ }
+
+ template<typename predicate_type>
+ void wait(unique_lock<mutex>& m,predicate_type pred)
+ {
+ while(!pred()) wait(m);
+ }
+
+
+#if defined BOOST_THREAD_USES_DATETIME
+ bool timed_wait(unique_lock<mutex>& m,boost::system_time const& abs_time)
+ {
+ return do_wait(m,abs_time);
+ }
+
+ bool timed_wait(unique_lock<mutex>& m,boost::xtime const& abs_time)
+ {
+ return do_wait(m,system_time(abs_time));
+ }
+ template<typename duration_type>
+ bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration)
+ {
+ if (wait_duration.is_pos_infinity())
+ {
+ wait(m); // or do_wait(m,detail::timeout::sentinel());
+ return true;
+ }
+ if (wait_duration.is_special())
+ {
+ return true;
+ }
+ return do_wait(m,wait_duration.total_milliseconds());
+ }
+
+ template<typename predicate_type>
+ bool timed_wait(unique_lock<mutex>& m,boost::system_time const& abs_time,predicate_type pred)
+ {
+ return do_wait(m,abs_time,pred);
+ }
+ template<typename predicate_type>
+ bool timed_wait(unique_lock<mutex>& m,boost::xtime const& abs_time,predicate_type pred)
+ {
+ return do_wait(m,system_time(abs_time),pred);
+ }
+ template<typename duration_type,typename predicate_type>
+ bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration,predicate_type pred)
+ {
+ if (wait_duration.is_pos_infinity())
+ {
+ while (!pred())
+ {
+ wait(m); // or do_wait(m,detail::timeout::sentinel());
+ }
+ return true;
+ }
+ if (wait_duration.is_special())
+ {
+ return pred();
+ }
+ return do_wait(m,wait_duration.total_milliseconds(),pred);
+ }
+#endif
+#ifdef BOOST_THREAD_USES_CHRONO
+
+ template <class Clock, class Duration>
+ cv_status
+ wait_until(
+ unique_lock<mutex>& lock,
+ const chrono::time_point<Clock, Duration>& t)
+ {
+ using namespace chrono;
+ chrono::time_point<Clock, Duration> now = Clock::now();
+ if (t<=now) {
+ return cv_status::timeout;
+ }
+ do_wait(lock, ceil<milliseconds>(t-now).count());
+ return Clock::now() < t ? cv_status::no_timeout :
+ cv_status::timeout;
+ }
+
+ template <class Rep, class Period>
+ cv_status
+ wait_for(
+ unique_lock<mutex>& lock,
+ const chrono::duration<Rep, Period>& d)
+ {
+ using namespace chrono;
+ if (d<=chrono::duration<Rep, Period>::zero()) {
+ return cv_status::timeout;
+ }
+
+ steady_clock::time_point c_now = steady_clock::now();
+ do_wait(lock, ceil<milliseconds>(d).count());
+ return steady_clock::now() - c_now < d ? cv_status::no_timeout :
+ cv_status::timeout;
+ }
+
+ template <class Clock, class Duration, class Predicate>
+ bool
+ wait_until(
+ unique_lock<mutex>& lock,
+ const chrono::time_point<Clock, Duration>& t,
+ Predicate pred)
+ {
+ while (!pred())
+ {
+ if (wait_until(lock, t) == cv_status::timeout)
+ return pred();
+ }
+ return true;
+ }
+ template <class Rep, class Period, class Predicate>
+ bool
+ wait_for(
+ unique_lock<mutex>& lock,
+ const chrono::duration<Rep, Period>& d,
+ Predicate pred)
+ {
+ return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred));
+ }
+#endif
+ };
+
+ class condition_variable_any:
+ private detail::basic_condition_variable
+ {
+ public:
+ BOOST_THREAD_NO_COPYABLE(condition_variable_any)
+ condition_variable_any()
+ {}
+
+ using detail::basic_condition_variable::notify_one;
+ using detail::basic_condition_variable::notify_all;
+
+ template<typename lock_type>
+ void wait(lock_type& m)
+ {
+ do_wait(m,detail::timeout::sentinel());
+ }
+
+ template<typename lock_type,typename predicate_type>
+ void wait(lock_type& m,predicate_type pred)
+ {
+ while(!pred()) wait(m);
+ }
+
+#if defined BOOST_THREAD_USES_DATETIME
+ template<typename lock_type>
+ bool timed_wait(lock_type& m,boost::system_time const& abs_time)
+ {
+ return do_wait(m,abs_time);
+ }
+
+ template<typename lock_type>
+ bool timed_wait(lock_type& m,boost::xtime const& abs_time)
+ {
+ return do_wait(m,system_time(abs_time));
+ }
+
+ template<typename lock_type,typename duration_type>
+ bool timed_wait(lock_type& m,duration_type const& wait_duration)
+ {
+ return do_wait(m,wait_duration.total_milliseconds());
+ }
+
+ template<typename lock_type,typename predicate_type>
+ bool timed_wait(lock_type& m,boost::system_time const& abs_time,predicate_type pred)
+ {
+ return do_wait(m,abs_time,pred);
+ }
+
+ template<typename lock_type,typename predicate_type>
+ bool timed_wait(lock_type& m,boost::xtime const& abs_time,predicate_type pred)
+ {
+ return do_wait(m,system_time(abs_time),pred);
+ }
+
+ template<typename lock_type,typename duration_type,typename predicate_type>
+ bool timed_wait(lock_type& m,duration_type const& wait_duration,predicate_type pred)
+ {
+ return do_wait(m,wait_duration.total_milliseconds(),pred);
+ }
+#endif
+#ifdef BOOST_THREAD_USES_CHRONO
+
+ template <class lock_type, class Clock, class Duration>
+ cv_status
+ wait_until(
+ lock_type& lock,
+ const chrono::time_point<Clock, Duration>& t)
+ {
+ using namespace chrono;
+ chrono::time_point<Clock, Duration> now = Clock::now();
+ if (t<=now) {
+ return cv_status::timeout;
+ }
+ do_wait(lock, ceil<milliseconds>(t-now).count());
+ return Clock::now() < t ? cv_status::no_timeout :
+ cv_status::timeout;
+ }
+
+ template <class lock_type, class Rep, class Period>
+ cv_status
+ wait_for(
+ lock_type& lock,
+ const chrono::duration<Rep, Period>& d)
+ {
+ using namespace chrono;
+ if (d<=chrono::duration<Rep, Period>::zero()) {
+ return cv_status::timeout;
+ }
+ steady_clock::time_point c_now = steady_clock::now();
+ do_wait(lock, ceil<milliseconds>(d).count());
+ return steady_clock::now() - c_now < d ? cv_status::no_timeout :
+ cv_status::timeout;
+ }
+
+ template <class lock_type, class Clock, class Duration, class Predicate>
+ bool
+ wait_until(
+ lock_type& lock,
+ const chrono::time_point<Clock, Duration>& t,
+ Predicate pred)
+ {
+ while (!pred())
+ {
+ if (wait_until(lock, t) == cv_status::timeout)
+ return pred();
+ }
+ return true;
+ }
+
+ template <class lock_type, class Rep, class Period, class Predicate>
+ bool
+ wait_for(
+ lock_type& lock,
+ const chrono::duration<Rep, Period>& d,
+ Predicate pred)
+ {
+ return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred));
+ }
+#endif
+ };
+
+ BOOST_THREAD_DECL void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/win32/interlocked_read.hpp b/src/third_party/boost-1.60.0/boost/thread/win32/interlocked_read.hpp
new file mode 100644
index 00000000000..2ad3fe9017a
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/win32/interlocked_read.hpp
@@ -0,0 +1,77 @@
+#ifndef BOOST_THREAD_DETAIL_INTERLOCKED_READ_WIN32_HPP
+#define BOOST_THREAD_DETAIL_INTERLOCKED_READ_WIN32_HPP
+
+// interlocked_read_win32.hpp
+//
+// (C) Copyright 2005-8 Anthony Williams
+// (C) Copyright 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)
+
+#include <boost/detail/interlocked.hpp>
+#include <boost/thread/detail/config.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+#ifdef BOOST_MSVC
+
+namespace boost
+{
+ namespace detail
+ {
+ // Since VS2005 volatile reads always acquire
+ inline long interlocked_read_acquire(long volatile* x) BOOST_NOEXCEPT
+ {
+ long const res=*x;
+ return res;
+ }
+ inline void* interlocked_read_acquire(void* volatile* x) BOOST_NOEXCEPT
+ {
+ void* const res=*x;
+ return res;
+ }
+
+ // Since VS2005 volatile writes always release
+ inline void interlocked_write_release(long volatile* x,long value) BOOST_NOEXCEPT
+ {
+ *x=value;
+ }
+ inline void interlocked_write_release(void* volatile* x,void* value) BOOST_NOEXCEPT
+ {
+ *x=value;
+ }
+ }
+}
+
+#else
+
+namespace boost
+{
+ namespace detail
+ {
+ inline long interlocked_read_acquire(long volatile* x) BOOST_NOEXCEPT
+ {
+ return BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,0,0);
+ }
+ inline void* interlocked_read_acquire(void* volatile* x) BOOST_NOEXCEPT
+ {
+ return BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(x,0,0);
+ }
+ inline void interlocked_write_release(long volatile* x,long value) BOOST_NOEXCEPT
+ {
+ BOOST_INTERLOCKED_EXCHANGE(x,value);
+ }
+ inline void interlocked_write_release(void* volatile* x,void* value) BOOST_NOEXCEPT
+ {
+ BOOST_INTERLOCKED_EXCHANGE_POINTER(x,value);
+ }
+ }
+}
+
+#endif
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/win32/mfc_thread_init.hpp b/src/third_party/boost-1.60.0/boost/thread/win32/mfc_thread_init.hpp
new file mode 100644
index 00000000000..e866f8949f5
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/win32/mfc_thread_init.hpp
@@ -0,0 +1,40 @@
+#ifndef BOOST_THREAD_WIN32_MFC_THREAD_INIT_HPP
+#define BOOST_THREAD_WIN32_MFC_THREAD_INIT_HPP
+// Distributed under the 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 2008 Anthony Williams
+// (C) Copyright 2011-2012 Vicente J. Botet Escriba
+
+
+// check if we use MFC
+#ifdef _AFXDLL
+# if defined(_AFXEXT)
+
+// can't use ExtRawDllMain from afxdllx.h as it also defines the symbol _pRawDllMain
+extern "C"
+inline BOOL WINAPI ExtRawDllMain(HINSTANCE, DWORD dwReason, LPVOID)
+{
+ if (dwReason == DLL_PROCESS_ATTACH)
+ {
+ // save critical data pointers before running the constructors
+ AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
+ pModuleState->m_pClassInit = pModuleState->m_classList;
+ pModuleState->m_pFactoryInit = pModuleState->m_factoryList;
+ pModuleState->m_classList.m_pHead = NULL;
+ pModuleState->m_factoryList.m_pHead = NULL;
+ }
+ return TRUE; // ok
+}
+
+extern "C" __declspec(selectany) BOOL (WINAPI * const _pRawDllMainOrig)(HANDLE, DWORD, LPVOID) = &ExtRawDllMain;
+
+# elif defined(_USRDLL)
+
+extern "C" BOOL WINAPI RawDllMain(HANDLE, DWORD dwReason, LPVOID);
+extern "C" __declspec(selectany) BOOL (WINAPI * const _pRawDllMainOrig)(HANDLE, DWORD, LPVOID) = &RawDllMain;
+
+# endif
+#endif
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/win32/mutex.hpp b/src/third_party/boost-1.60.0/boost/thread/win32/mutex.hpp
new file mode 100644
index 00000000000..01544784b5b
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/win32/mutex.hpp
@@ -0,0 +1,72 @@
+#ifndef BOOST_THREAD_WIN32_MUTEX_HPP
+#define BOOST_THREAD_WIN32_MUTEX_HPP
+// (C) Copyright 2005-7 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)
+
+#include <boost/thread/win32/basic_timed_mutex.hpp>
+#include <boost/thread/exceptions.hpp>
+#if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
+#include <boost/thread/lock_types.hpp>
+#endif
+#include <boost/thread/detail/delete.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ namespace detail
+ {
+ typedef ::boost::detail::basic_timed_mutex underlying_mutex;
+ }
+
+ class mutex:
+ public ::boost::detail::underlying_mutex
+ {
+ public:
+ BOOST_THREAD_NO_COPYABLE(mutex)
+ mutex()
+ {
+ initialize();
+ }
+ ~mutex()
+ {
+ destroy();
+ }
+
+#if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
+ typedef unique_lock<mutex> scoped_lock;
+ typedef detail::try_lock_wrapper<mutex> scoped_try_lock;
+#endif
+ };
+
+ typedef mutex try_mutex;
+
+ class timed_mutex:
+ public ::boost::detail::basic_timed_mutex
+ {
+ public:
+ BOOST_THREAD_NO_COPYABLE(timed_mutex)
+ timed_mutex()
+ {
+ initialize();
+ }
+
+ ~timed_mutex()
+ {
+ destroy();
+ }
+
+#if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
+ typedef unique_lock<timed_mutex> scoped_timed_lock;
+ typedef detail::try_lock_wrapper<timed_mutex> scoped_try_lock;
+ typedef scoped_timed_lock scoped_lock;
+#endif
+ };
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/win32/once.hpp b/src/third_party/boost-1.60.0/boost/thread/win32/once.hpp
new file mode 100644
index 00000000000..24eb0f29d06
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/win32/once.hpp
@@ -0,0 +1,1087 @@
+#ifndef BOOST_THREAD_WIN32_ONCE_HPP
+#define BOOST_THREAD_WIN32_ONCE_HPP
+
+// once.hpp
+//
+// (C) Copyright 2005-7 Anthony Williams
+// (C) Copyright 2005 John Maddock
+// (C) Copyright 2011-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)
+
+#include <cstring>
+#include <cstddef>
+#include <boost/assert.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/detail/interlocked.hpp>
+#include <boost/thread/win32/thread_primitives.hpp>
+#include <boost/thread/win32/interlocked_read.hpp>
+#include <boost/core/no_exceptions_support.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/detail/invoke.hpp>
+
+#include <boost/bind.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+#ifdef BOOST_NO_STDC_NAMESPACE
+namespace std
+{
+ using ::memcpy;
+ using ::ptrdiff_t;
+}
+#endif
+
+namespace boost
+{
+ struct once_flag;
+ namespace detail
+ {
+ struct once_context;
+
+ inline bool enter_once_region(once_flag& flag, once_context& ctx) BOOST_NOEXCEPT;
+ inline void commit_once_region(once_flag& flag, once_context& ctx) BOOST_NOEXCEPT;
+ inline void rollback_once_region(once_flag& flag, once_context& ctx) BOOST_NOEXCEPT;
+ }
+
+#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11
+
+ struct once_flag
+ {
+ BOOST_THREAD_NO_COPYABLE(once_flag)
+ BOOST_CONSTEXPR once_flag() BOOST_NOEXCEPT
+ : status(0), count(0)
+ {}
+ long status;
+ long count;
+ private:
+ friend inline bool enter_once_region(once_flag& flag, detail::once_context& ctx) BOOST_NOEXCEPT;
+ friend inline void commit_once_region(once_flag& flag, detail::once_context& ctx) BOOST_NOEXCEPT;
+ friend inline void rollback_once_region(once_flag& flag, detail::once_context& ctx) BOOST_NOEXCEPT;
+ };
+
+#define BOOST_ONCE_INIT once_flag()
+#else // BOOST_THREAD_PROVIDES_ONCE_CXX11
+
+ struct once_flag
+ {
+ long status;
+ long count;
+ };
+
+#define BOOST_ONCE_INIT {0,0}
+#endif // BOOST_THREAD_PROVIDES_ONCE_CXX11
+
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+#define BOOST_THREAD_INVOKE_RET_VOID detail::invoke
+#define BOOST_THREAD_INVOKE_RET_VOID_CALL
+#elif defined BOOST_THREAD_PROVIDES_INVOKE_RET
+#define BOOST_THREAD_INVOKE_RET_VOID detail::invoke<void>
+#define BOOST_THREAD_INVOKE_RET_VOID_CALL
+#else
+#define BOOST_THREAD_INVOKE_RET_VOID boost::bind
+#define BOOST_THREAD_INVOKE_RET_VOID_CALL ()
+#endif
+
+ namespace detail
+ {
+#ifdef BOOST_NO_ANSI_APIS
+ typedef wchar_t once_char_type;
+#else
+ typedef char once_char_type;
+#endif
+ unsigned const once_mutex_name_fixed_length=54;
+ unsigned const once_mutex_name_length=once_mutex_name_fixed_length+
+ sizeof(void*)*2+sizeof(unsigned long)*2+1;
+
+ template <class I>
+ void int_to_string(I p, once_char_type* buf)
+ {
+ for(unsigned i=0; i < sizeof(I)*2; ++i,++buf)
+ {
+#ifdef BOOST_NO_ANSI_APIS
+ once_char_type const a=L'A';
+#else
+ once_char_type const a='A';
+#endif
+ *buf = a + static_cast<once_char_type>((p >> (i*4)) & 0x0f);
+ }
+ *buf = 0;
+ }
+
+ inline void name_once_mutex(once_char_type* mutex_name,void* flag_address)
+ {
+#ifdef BOOST_NO_ANSI_APIS
+ static const once_char_type fixed_mutex_name[]=L"Local\\{C15730E2-145C-4c5e-B005-3BC753F42475}-once-flag";
+#else
+ static const once_char_type fixed_mutex_name[]="Local\\{C15730E2-145C-4c5e-B005-3BC753F42475}-once-flag";
+#endif
+ BOOST_STATIC_ASSERT(sizeof(fixed_mutex_name) ==
+ (sizeof(once_char_type)*(once_mutex_name_fixed_length+1)));
+
+ std::memcpy(mutex_name,fixed_mutex_name,sizeof(fixed_mutex_name));
+ detail::int_to_string(reinterpret_cast<std::ptrdiff_t>(flag_address),
+ mutex_name + once_mutex_name_fixed_length);
+ detail::int_to_string(win32::GetCurrentProcessId(),
+ mutex_name + once_mutex_name_fixed_length + sizeof(void*)*2);
+ }
+
+ inline void* open_once_event(once_char_type* mutex_name,void* flag_address)
+ {
+ if(!*mutex_name)
+ {
+ name_once_mutex(mutex_name,flag_address);
+ }
+
+#ifdef BOOST_NO_ANSI_APIS
+ return ::boost::detail::win32::OpenEventW(
+#else
+ return ::boost::detail::win32::OpenEventA(
+#endif
+ ::boost::detail::win32::synchronize |
+ ::boost::detail::win32::event_modify_state,
+ false,
+ mutex_name);
+ }
+
+ inline void* create_once_event(once_char_type* mutex_name,void* flag_address)
+ {
+ if(!*mutex_name)
+ {
+ name_once_mutex(mutex_name,flag_address);
+ }
+
+ return ::boost::detail::win32::create_event(
+ mutex_name,
+ ::boost::detail::win32::manual_reset_event,
+ ::boost::detail::win32::event_initially_reset);
+ }
+
+ struct once_context {
+ long const function_complete_flag_value;
+ long const running_value;
+ bool counted;
+ detail::win32::handle_manager event_handle;
+ detail::once_char_type mutex_name[once_mutex_name_length];
+ once_context() :
+ function_complete_flag_value(0xc15730e2),
+ running_value(0x7f0725e3),
+ counted(false)
+ {
+ mutex_name[0]=0;
+ }
+ };
+ enum once_action {try_, break_, continue_};
+
+ inline bool enter_once_region(once_flag& flag, once_context& ctx) BOOST_NOEXCEPT
+ {
+ long status=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&flag.status,ctx.running_value,0);
+ if(!status)
+ {
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::open_once_event(ctx.mutex_name,&flag);
+ }
+ if(ctx.event_handle)
+ {
+ ::boost::detail::win32::ResetEvent(ctx.event_handle);
+ }
+ return true;
+ }
+ return false;
+ }
+ inline void commit_once_region(once_flag& flag, once_context& ctx) BOOST_NOEXCEPT
+ {
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ }
+ BOOST_INTERLOCKED_EXCHANGE(&flag.status,ctx.function_complete_flag_value);
+ if(!ctx.event_handle &&
+ (::boost::detail::interlocked_read_acquire(&flag.count)>1))
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ }
+ if(ctx.event_handle)
+ {
+ ::boost::detail::win32::SetEvent(ctx.event_handle);
+ }
+ }
+ inline void rollback_once_region(once_flag& flag, once_context& ctx) BOOST_NOEXCEPT
+ {
+ BOOST_INTERLOCKED_EXCHANGE(&flag.status,0);
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::open_once_event(ctx.mutex_name,&flag);
+ }
+ if(ctx.event_handle)
+ {
+ ::boost::detail::win32::SetEvent(ctx.event_handle);
+ }
+ }
+ }
+
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+//#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
+ inline void call_once(once_flag& flag, void (*f)())
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ f();
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
+ ctx.event_handle,::boost::detail::win32::infinite, 0));
+ }
+ }
+//#endif
+ template<typename Function>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ f();
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
+ ctx.event_handle,::boost::detail::win32::infinite,0));
+ }
+ }
+ template<typename Function, class A, class ...ArgTypes>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(A) a, BOOST_THREAD_RV_REF(ArgTypes)... args)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<A>(a)),
+ thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
+ ctx.event_handle,::boost::detail::win32::infinite,0));
+ }
+ }
+#else
+#if ! defined(BOOST_MSVC) && ! defined(BOOST_INTEL)
+ template<typename Function>
+ void call_once(once_flag& flag,Function f)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ f();
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
+ ctx.event_handle,::boost::detail::win32::infinite,0));
+ }
+ }
+ template<typename Function, typename T1>
+ void call_once(once_flag& flag,Function f, T1 p1)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(f,p1) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
+ ctx.event_handle,::boost::detail::win32::infinite,0));
+ }
+ }
+ template<typename Function, typename T1, typename T2>
+ void call_once(once_flag& flag,Function f, T1 p1, T2 p2)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(f,p1,p2) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
+ ctx.event_handle,::boost::detail::win32::infinite,0));
+ }
+ }
+ template<typename Function, typename T1, typename T2, typename T3>
+ void call_once(once_flag& flag,Function f, T1 p1, T2 p2, T3 p3)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(f,p1,p2,p3) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
+ ctx.event_handle,::boost::detail::win32::infinite,0));
+ }
+ }
+#elif defined BOOST_NO_CXX11_RVALUE_REFERENCES
+
+ template<typename Function>
+ void call_once(once_flag& flag,Function const&f)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ f();
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
+ ctx.event_handle,::boost::detail::win32::infinite,0));
+ }
+ }
+ template<typename Function, typename T1>
+ void call_once(once_flag& flag,Function const&f, T1 const&p1)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(f,p1) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
+ ctx.event_handle,::boost::detail::win32::infinite,0));
+ }
+ }
+ template<typename Function, typename T1, typename T2>
+ void call_once(once_flag& flag,Function const&f, T1 const&p1, T2 const&p2)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(f,p1,p2) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
+ ctx.event_handle,::boost::detail::win32::infinite,0));
+ }
+ }
+ template<typename Function, typename T1, typename T2, typename T3>
+ void call_once(once_flag& flag,Function const&f, T1 const&p1, T2 const&p2, T3 const&p3)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(f,p1,p2,p3) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
+ ctx.event_handle,::boost::detail::win32::infinite,0));
+ }
+ }
+#endif
+#if 1
+#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
+ inline void call_once(once_flag& flag, void (*f)())
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ f();
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
+ ctx.event_handle,::boost::detail::win32::infinite,0));
+ }
+ }
+ template<typename T1>
+ void call_once(once_flag& flag,void (*f)(BOOST_THREAD_RV_REF(T1)), BOOST_THREAD_RV_REF(T1) p1)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ f(
+ thread_detail::decay_copy(boost::forward<T1>(p1))
+ );
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
+ ctx.event_handle,::boost::detail::win32::infinite,0));
+ }
+ }
+ template<typename Function, typename T1, typename T2>
+ void call_once(once_flag& flag,void (*f)(BOOST_THREAD_RV_REF(T1),BOOST_THREAD_RV_REF(T2)), BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ f(
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
+ thread_detail::decay_copy(boost::forward<T2>(p2))
+ );
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
+ ctx.event_handle,::boost::detail::win32::infinite,0));
+ }
+ }
+ template<typename Function, typename T1, typename T2, typename T3>
+ void call_once(once_flag& flag,void (*f)(BOOST_THREAD_RV_REF(T1),BOOST_THREAD_RV_REF(T2)), BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2, BOOST_THREAD_RV_REF(T3) p3)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ f(
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
+ thread_detail::decay_copy(boost::forward<T2>(p2)),
+ thread_detail::decay_copy(boost::forward<T3>(p3))
+ );
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
+ ctx.event_handle,::boost::detail::win32::infinite,0));
+ }
+ }
+#endif
+ template<typename Function>
+ void call_once(once_flag& flag,BOOST_THREAD_RV_REF(Function) f)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ f();
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
+ ctx.event_handle,::boost::detail::win32::infinite,0));
+ }
+ }
+
+ template<typename Function, typename T1>
+ void call_once(once_flag& flag,BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<T1>(p1))
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
+ ctx.event_handle,::boost::detail::win32::infinite,0));
+ }
+ }
+ template<typename Function, typename T1, typename T2>
+ void call_once(once_flag& flag,BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
+ thread_detail::decay_copy(boost::forward<T2>(p2))
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
+ ctx.event_handle,::boost::detail::win32::infinite,0));
+ }
+ }
+ template<typename Function, typename T1, typename T2, typename T3>
+ void call_once(once_flag& flag,BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2, BOOST_THREAD_RV_REF(T3) p3)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
+ thread_detail::decay_copy(boost::forward<T2>(p2)),
+ thread_detail::decay_copy(boost::forward<T3>(p3))
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
+ ctx.event_handle,::boost::detail::win32::infinite,0));
+ }
+ }
+
+#endif
+#endif
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/win32/recursive_mutex.hpp b/src/third_party/boost-1.60.0/boost/thread/win32/recursive_mutex.hpp
new file mode 100644
index 00000000000..1f0f7f5e5fd
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/win32/recursive_mutex.hpp
@@ -0,0 +1,70 @@
+#ifndef BOOST_RECURSIVE_MUTEX_WIN32_HPP
+#define BOOST_RECURSIVE_MUTEX_WIN32_HPP
+
+// recursive_mutex.hpp
+//
+// (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)
+
+
+#include <boost/thread/win32/basic_recursive_mutex.hpp>
+#include <boost/thread/exceptions.hpp>
+#include <boost/thread/detail/delete.hpp>
+#if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
+#include <boost/thread/lock_types.hpp>
+#endif
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ class recursive_mutex:
+ public ::boost::detail::basic_recursive_mutex
+ {
+ public:
+ BOOST_THREAD_NO_COPYABLE(recursive_mutex)
+ recursive_mutex()
+ {
+ ::boost::detail::basic_recursive_mutex::initialize();
+ }
+ ~recursive_mutex()
+ {
+ ::boost::detail::basic_recursive_mutex::destroy();
+ }
+
+#if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
+ typedef unique_lock<recursive_mutex> scoped_lock;
+ typedef detail::try_lock_wrapper<recursive_mutex> scoped_try_lock;
+#endif
+ };
+
+ typedef recursive_mutex recursive_try_mutex;
+
+ class recursive_timed_mutex:
+ public ::boost::detail::basic_recursive_timed_mutex
+ {
+ public:
+ BOOST_THREAD_NO_COPYABLE(recursive_timed_mutex)
+ recursive_timed_mutex()
+ {
+ ::boost::detail::basic_recursive_timed_mutex::initialize();
+ }
+ ~recursive_timed_mutex()
+ {
+ ::boost::detail::basic_recursive_timed_mutex::destroy();
+ }
+
+#if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
+ typedef unique_lock<recursive_timed_mutex> scoped_timed_lock;
+ typedef detail::try_lock_wrapper<recursive_timed_mutex> scoped_try_lock;
+ typedef scoped_timed_lock scoped_lock;
+#endif
+ };
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/win32/shared_mutex.hpp b/src/third_party/boost-1.60.0/boost/thread/win32/shared_mutex.hpp
new file mode 100644
index 00000000000..b7822d1142f
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/win32/shared_mutex.hpp
@@ -0,0 +1,903 @@
+#ifndef BOOST_THREAD_WIN32_SHARED_MUTEX_HPP
+#define BOOST_THREAD_WIN32_SHARED_MUTEX_HPP
+
+// (C) Copyright 2006-8 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)
+
+#include <boost/assert.hpp>
+#include <boost/detail/interlocked.hpp>
+#include <boost/thread/win32/thread_primitives.hpp>
+#include <boost/static_assert.hpp>
+#include <limits.h>
+#include <boost/thread/thread_time.hpp>
+#ifdef BOOST_THREAD_USES_CHRONO
+#include <boost/chrono/system_clocks.hpp>
+#include <boost/chrono/ceil.hpp>
+#endif
+#include <boost/thread/detail/delete.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ class shared_mutex
+ {
+ private:
+ struct state_data
+ {
+ unsigned shared_count:11,
+ shared_waiting:11,
+ exclusive:1,
+ upgrade:1,
+ exclusive_waiting:7,
+ exclusive_waiting_blocked:1;
+
+ friend bool operator==(state_data const& lhs,state_data const& rhs)
+ {
+ return *reinterpret_cast<unsigned const*>(&lhs)==*reinterpret_cast<unsigned const*>(&rhs);
+ }
+ };
+
+
+ template<typename T>
+ T interlocked_compare_exchange(T* target,T new_value,T comparand)
+ {
+ BOOST_STATIC_ASSERT(sizeof(T)==sizeof(long));
+ long const res=BOOST_INTERLOCKED_COMPARE_EXCHANGE(reinterpret_cast<long*>(target),
+ *reinterpret_cast<long*>(&new_value),
+ *reinterpret_cast<long*>(&comparand));
+ return *reinterpret_cast<T const*>(&res);
+ }
+
+ enum
+ {
+ unlock_sem = 0,
+ exclusive_sem = 1
+ };
+
+ state_data state;
+ detail::win32::handle semaphores[2];
+ detail::win32::handle upgrade_sem;
+
+ void release_waiters(state_data old_state)
+ {
+ if(old_state.exclusive_waiting)
+ {
+ BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[exclusive_sem],1,0)!=0);
+ }
+
+ if(old_state.shared_waiting || old_state.exclusive_waiting)
+ {
+ BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],old_state.shared_waiting + (old_state.exclusive_waiting?1:0),0)!=0);
+ }
+ }
+ void release_shared_waiters(state_data old_state)
+ {
+ if(old_state.shared_waiting || old_state.exclusive_waiting)
+ {
+ BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],old_state.shared_waiting + (old_state.exclusive_waiting?1:0),0)!=0);
+ }
+ }
+
+ public:
+ BOOST_THREAD_NO_COPYABLE(shared_mutex)
+ shared_mutex()
+ {
+ semaphores[unlock_sem]=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
+ semaphores[exclusive_sem]=detail::win32::create_anonymous_semaphore_nothrow(0,LONG_MAX);
+ if (!semaphores[exclusive_sem])
+ {
+ detail::win32::release_semaphore(semaphores[unlock_sem],LONG_MAX);
+ boost::throw_exception(thread_resource_error());
+ }
+ upgrade_sem=detail::win32::create_anonymous_semaphore_nothrow(0,LONG_MAX);
+ if (!upgrade_sem)
+ {
+ detail::win32::release_semaphore(semaphores[unlock_sem],LONG_MAX);
+ detail::win32::release_semaphore(semaphores[exclusive_sem],LONG_MAX);
+ boost::throw_exception(thread_resource_error());
+ }
+ state_data state_={0,0,0,0,0,0};
+ state=state_;
+ }
+
+ ~shared_mutex()
+ {
+ detail::win32::CloseHandle(upgrade_sem);
+ detail::win32::CloseHandle(semaphores[unlock_sem]);
+ detail::win32::CloseHandle(semaphores[exclusive_sem]);
+ }
+
+ bool try_lock_shared()
+ {
+ state_data old_state=state;
+ for(;;)
+ {
+ state_data new_state=old_state;
+ if(!new_state.exclusive && !new_state.exclusive_waiting_blocked)
+ {
+ ++new_state.shared_count;
+ if(!new_state.shared_count)
+ {
+ return false;
+ }
+ }
+
+ state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+ if(current_state==old_state)
+ {
+ break;
+ }
+ old_state=current_state;
+ }
+ return !(old_state.exclusive| old_state.exclusive_waiting_blocked);
+ }
+
+ void lock_shared()
+ {
+
+#if defined BOOST_THREAD_USES_DATETIME
+ BOOST_VERIFY(timed_lock_shared(::boost::detail::get_system_time_sentinel()));
+#else
+ BOOST_VERIFY(try_lock_shared_until(chrono::steady_clock::now()));
+#endif
+ }
+
+#if defined BOOST_THREAD_USES_DATETIME
+ template<typename TimeDuration>
+ bool timed_lock_shared(TimeDuration const & relative_time)
+ {
+ return timed_lock_shared(get_system_time()+relative_time);
+ }
+ bool timed_lock_shared(boost::system_time const& wait_until)
+ {
+ for(;;)
+ {
+ state_data old_state=state;
+ for(;;)
+ {
+ state_data new_state=old_state;
+ if(new_state.exclusive || new_state.exclusive_waiting_blocked)
+ {
+ ++new_state.shared_waiting;
+ if(!new_state.shared_waiting)
+ {
+ boost::throw_exception(boost::lock_error());
+ }
+ }
+ else
+ {
+ ++new_state.shared_count;
+ if(!new_state.shared_count)
+ {
+ boost::throw_exception(boost::lock_error());
+ }
+ }
+
+ state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+ if(current_state==old_state)
+ {
+ break;
+ }
+ old_state=current_state;
+ }
+
+ if(!(old_state.exclusive| old_state.exclusive_waiting_blocked))
+ {
+ return true;
+ }
+
+ unsigned long const res=detail::win32::WaitForSingleObjectEx(semaphores[unlock_sem],::boost::detail::get_milliseconds_until(wait_until), 0);
+ if(res==detail::win32::timeout)
+ {
+ for(;;)
+ {
+ state_data new_state=old_state;
+ if(new_state.exclusive || new_state.exclusive_waiting_blocked)
+ {
+ if(new_state.shared_waiting)
+ {
+ --new_state.shared_waiting;
+ }
+ }
+ else
+ {
+ ++new_state.shared_count;
+ if(!new_state.shared_count)
+ {
+ return false;
+ }
+ }
+
+ state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+ if(current_state==old_state)
+ {
+ break;
+ }
+ old_state=current_state;
+ }
+
+ if(!(old_state.exclusive| old_state.exclusive_waiting_blocked))
+ {
+ return true;
+ }
+ return false;
+ }
+
+ BOOST_ASSERT(res==0);
+ }
+ }
+#endif
+
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_lock_shared_until(chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool try_lock_shared_until(const chrono::time_point<Clock, Duration>& t)
+ {
+ using namespace chrono;
+ system_clock::time_point s_now = system_clock::now();
+ typename Clock::time_point c_now = Clock::now();
+ return try_lock_shared_until(s_now + ceil<system_clock::duration>(t - c_now));
+ }
+ template <class Duration>
+ bool try_lock_shared_until(const chrono::time_point<chrono::system_clock, Duration>& t)
+ {
+ using namespace chrono;
+ typedef time_point<chrono::system_clock, chrono::system_clock::duration> sys_tmpt;
+ return try_lock_shared_until(sys_tmpt(chrono::ceil<chrono::system_clock::duration>(t.time_since_epoch())));
+ }
+ bool try_lock_shared_until(const chrono::time_point<chrono::system_clock, chrono::system_clock::duration>& tp)
+ {
+ for(;;)
+ {
+ state_data old_state=state;
+ for(;;)
+ {
+ state_data new_state=old_state;
+ if(new_state.exclusive || new_state.exclusive_waiting_blocked)
+ {
+ ++new_state.shared_waiting;
+ if(!new_state.shared_waiting)
+ {
+ boost::throw_exception(boost::lock_error());
+ }
+ }
+ else
+ {
+ ++new_state.shared_count;
+ if(!new_state.shared_count)
+ {
+ boost::throw_exception(boost::lock_error());
+ }
+ }
+
+ state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+ if(current_state==old_state)
+ {
+ break;
+ }
+ old_state=current_state;
+ }
+
+ if(!(old_state.exclusive| old_state.exclusive_waiting_blocked))
+ {
+ return true;
+ }
+
+ chrono::system_clock::time_point n = chrono::system_clock::now();
+ unsigned long res;
+ if (tp>n) {
+ chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-n);
+ res=detail::win32::WaitForSingleObjectEx(semaphores[unlock_sem],
+ static_cast<unsigned long>(rel_time.count()), 0);
+ } else {
+ res=detail::win32::timeout;
+ }
+ if(res==detail::win32::timeout)
+ {
+ for(;;)
+ {
+ state_data new_state=old_state;
+ if(new_state.exclusive || new_state.exclusive_waiting_blocked)
+ {
+ if(new_state.shared_waiting)
+ {
+ --new_state.shared_waiting;
+ }
+ }
+ else
+ {
+ ++new_state.shared_count;
+ if(!new_state.shared_count)
+ {
+ return false;
+ }
+ }
+
+ state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+ if(current_state==old_state)
+ {
+ break;
+ }
+ old_state=current_state;
+ }
+
+ if(!(old_state.exclusive| old_state.exclusive_waiting_blocked))
+ {
+ return true;
+ }
+ return false;
+ }
+
+ BOOST_ASSERT(res==0);
+ }
+ }
+#endif
+
+ void unlock_shared()
+ {
+ state_data old_state=state;
+ for(;;)
+ {
+ state_data new_state=old_state;
+ bool const last_reader=!--new_state.shared_count;
+
+ if(last_reader)
+ {
+ if(new_state.upgrade)
+ {
+ new_state.upgrade=false;
+ new_state.exclusive=true;
+ }
+ else
+ {
+ if(new_state.exclusive_waiting)
+ {
+ --new_state.exclusive_waiting;
+ new_state.exclusive_waiting_blocked=false;
+ }
+ new_state.shared_waiting=0;
+ }
+ }
+
+ state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+ if(current_state==old_state)
+ {
+ if(last_reader)
+ {
+ if(old_state.upgrade)
+ {
+ BOOST_VERIFY(detail::win32::ReleaseSemaphore(upgrade_sem,1,0)!=0);
+ }
+ else
+ {
+ release_waiters(old_state);
+ }
+ }
+ break;
+ }
+ old_state=current_state;
+ }
+ }
+
+ void lock()
+ {
+
+#if defined BOOST_THREAD_USES_DATETIME
+ BOOST_VERIFY(timed_lock(::boost::detail::get_system_time_sentinel()));
+#else
+ BOOST_VERIFY(try_lock_until(chrono::steady_clock::now()));
+#endif
+ }
+
+#if defined BOOST_THREAD_USES_DATETIME
+ template<typename TimeDuration>
+ bool timed_lock(TimeDuration const & relative_time)
+ {
+ return timed_lock(get_system_time()+relative_time);
+ }
+#endif
+
+ bool try_lock()
+ {
+ state_data old_state=state;
+ for(;;)
+ {
+ state_data new_state=old_state;
+ if(new_state.shared_count || new_state.exclusive)
+ {
+ return false;
+ }
+ else
+ {
+ new_state.exclusive=true;
+ }
+
+ state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+ if(current_state==old_state)
+ {
+ break;
+ }
+ old_state=current_state;
+ }
+ return true;
+ }
+
+
+#if defined BOOST_THREAD_USES_DATETIME
+ bool timed_lock(boost::system_time const& wait_until)
+ {
+ for(;;)
+ {
+ state_data old_state=state;
+
+ for(;;)
+ {
+ state_data new_state=old_state;
+ if(new_state.shared_count || new_state.exclusive)
+ {
+ ++new_state.exclusive_waiting;
+ if(!new_state.exclusive_waiting)
+ {
+ boost::throw_exception(boost::lock_error());
+ }
+
+ new_state.exclusive_waiting_blocked=true;
+ }
+ else
+ {
+ new_state.exclusive=true;
+ }
+
+ state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+ if(current_state==old_state)
+ {
+ break;
+ }
+ old_state=current_state;
+ }
+
+ if(!old_state.shared_count && !old_state.exclusive)
+ {
+ return true;
+ }
+ #ifndef UNDER_CE
+ const bool wait_all = true;
+ #else
+ const bool wait_all = false;
+ #endif
+ unsigned long const wait_res=detail::win32::WaitForMultipleObjectsEx(2,semaphores,wait_all,::boost::detail::get_milliseconds_until(wait_until), 0);
+ if(wait_res==detail::win32::timeout)
+ {
+ for(;;)
+ {
+ bool must_notify = false;
+ state_data new_state=old_state;
+ if(new_state.shared_count || new_state.exclusive)
+ {
+ if(new_state.exclusive_waiting)
+ {
+ if(!--new_state.exclusive_waiting)
+ {
+ new_state.exclusive_waiting_blocked=false;
+ must_notify = true;
+ }
+ }
+ }
+ else
+ {
+ new_state.exclusive=true;
+ }
+
+ state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+ if (must_notify)
+ {
+ BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],1,0)!=0);
+ }
+
+ if(current_state==old_state)
+ {
+ break;
+ }
+ old_state=current_state;
+ }
+ if(!old_state.shared_count && !old_state.exclusive)
+ {
+ return true;
+ }
+ return false;
+ }
+ BOOST_ASSERT(wait_res<2);
+ }
+ }
+#endif
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_lock_until(chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool try_lock_until(const chrono::time_point<Clock, Duration>& t)
+ {
+ using namespace chrono;
+ system_clock::time_point s_now = system_clock::now();
+ typename Clock::time_point c_now = Clock::now();
+ return try_lock_until(s_now + ceil<system_clock::duration>(t - c_now));
+ }
+ template <class Duration>
+ bool try_lock_until(const chrono::time_point<chrono::system_clock, Duration>& t)
+ {
+ using namespace chrono;
+ typedef time_point<chrono::system_clock, chrono::system_clock::duration> sys_tmpt;
+ return try_lock_until(sys_tmpt(chrono::ceil<chrono::system_clock::duration>(t.time_since_epoch())));
+ }
+ bool try_lock_until(const chrono::time_point<chrono::system_clock, chrono::system_clock::duration>& tp)
+ {
+ for(;;)
+ {
+ state_data old_state=state;
+
+ for(;;)
+ {
+ state_data new_state=old_state;
+ if(new_state.shared_count || new_state.exclusive)
+ {
+ ++new_state.exclusive_waiting;
+ if(!new_state.exclusive_waiting)
+ {
+ boost::throw_exception(boost::lock_error());
+ }
+
+ new_state.exclusive_waiting_blocked=true;
+ }
+ else
+ {
+ new_state.exclusive=true;
+ }
+
+ state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+ if(current_state==old_state)
+ {
+ break;
+ }
+ old_state=current_state;
+ }
+
+ if(!old_state.shared_count && !old_state.exclusive)
+ {
+ return true;
+ }
+ #ifndef UNDER_CE
+ const bool wait_all = true;
+ #else
+ const bool wait_all = false;
+ #endif
+
+ chrono::system_clock::time_point n = chrono::system_clock::now();
+ unsigned long wait_res;
+ if (tp>n) {
+ chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-chrono::system_clock::now());
+ wait_res=detail::win32::WaitForMultipleObjectsEx(2,semaphores,wait_all,
+ static_cast<unsigned long>(rel_time.count()), 0);
+ } else {
+ wait_res=detail::win32::timeout;
+ }
+ if(wait_res==detail::win32::timeout)
+ {
+ for(;;)
+ {
+ bool must_notify = false;
+ state_data new_state=old_state;
+ if(new_state.shared_count || new_state.exclusive)
+ {
+ if(new_state.exclusive_waiting)
+ {
+ if(!--new_state.exclusive_waiting)
+ {
+ new_state.exclusive_waiting_blocked=false;
+ must_notify = true;
+ }
+ }
+ }
+ else
+ {
+ new_state.exclusive=true;
+ }
+
+ state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+ if (must_notify)
+ {
+ BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],1,0)!=0);
+ }
+ if(current_state==old_state)
+ {
+ break;
+ }
+ old_state=current_state;
+ }
+ if(!old_state.shared_count && !old_state.exclusive)
+ {
+ return true;
+ }
+ return false;
+ }
+ BOOST_ASSERT(wait_res<2);
+ }
+ }
+#endif
+
+ void unlock()
+ {
+ state_data old_state=state;
+ for(;;)
+ {
+ state_data new_state=old_state;
+ new_state.exclusive=false;
+ if(new_state.exclusive_waiting)
+ {
+ --new_state.exclusive_waiting;
+ new_state.exclusive_waiting_blocked=false;
+ }
+ new_state.shared_waiting=0;
+
+ state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+ if(current_state==old_state)
+ {
+ break;
+ }
+ old_state=current_state;
+ }
+ release_waiters(old_state);
+ }
+
+ void lock_upgrade()
+ {
+ for(;;)
+ {
+ state_data old_state=state;
+ for(;;)
+ {
+ state_data new_state=old_state;
+ if(new_state.exclusive || new_state.exclusive_waiting_blocked || new_state.upgrade)
+ {
+ ++new_state.shared_waiting;
+ if(!new_state.shared_waiting)
+ {
+ boost::throw_exception(boost::lock_error());
+ }
+ }
+ else
+ {
+ ++new_state.shared_count;
+ if(!new_state.shared_count)
+ {
+ boost::throw_exception(boost::lock_error());
+ }
+ new_state.upgrade=true;
+ }
+
+ state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+ if(current_state==old_state)
+ {
+ break;
+ }
+ old_state=current_state;
+ }
+
+ if(!(old_state.exclusive|| old_state.exclusive_waiting_blocked|| old_state.upgrade))
+ {
+ return;
+ }
+
+ BOOST_VERIFY(!detail::win32::WaitForSingleObjectEx(semaphores[unlock_sem],detail::win32::infinite, 0));
+ }
+ }
+
+ bool try_lock_upgrade()
+ {
+ state_data old_state=state;
+ for(;;)
+ {
+ state_data new_state=old_state;
+ if(new_state.exclusive || new_state.exclusive_waiting_blocked || new_state.upgrade)
+ {
+ return false;
+ }
+ else
+ {
+ ++new_state.shared_count;
+ if(!new_state.shared_count)
+ {
+ return false;
+ }
+ new_state.upgrade=true;
+ }
+
+ state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+ if(current_state==old_state)
+ {
+ break;
+ }
+ old_state=current_state;
+ }
+ return true;
+ }
+
+ void unlock_upgrade()
+ {
+ state_data old_state=state;
+ for(;;)
+ {
+ state_data new_state=old_state;
+ new_state.upgrade=false;
+ bool const last_reader=!--new_state.shared_count;
+
+ new_state.shared_waiting=0;
+ if(last_reader)
+ {
+ if(new_state.exclusive_waiting)
+ {
+ --new_state.exclusive_waiting;
+ new_state.exclusive_waiting_blocked=false;
+ }
+ }
+
+ state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+ if(current_state==old_state)
+ {
+ if(last_reader)
+ {
+ release_waiters(old_state);
+ }
+ else {
+ release_shared_waiters(old_state);
+ }
+ // #7720
+ //else {
+ // release_waiters(old_state);
+ //}
+ break;
+ }
+ old_state=current_state;
+ }
+ }
+
+ void unlock_upgrade_and_lock()
+ {
+ state_data old_state=state;
+ for(;;)
+ {
+ state_data new_state=old_state;
+ bool const last_reader=!--new_state.shared_count;
+
+ if(last_reader)
+ {
+ new_state.upgrade=false;
+ new_state.exclusive=true;
+ }
+
+ state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+ if(current_state==old_state)
+ {
+ if(!last_reader)
+ {
+ BOOST_VERIFY(!detail::win32::WaitForSingleObjectEx(upgrade_sem,detail::win32::infinite, 0));
+ }
+ break;
+ }
+ old_state=current_state;
+ }
+ }
+
+ void unlock_and_lock_upgrade()
+ {
+ state_data old_state=state;
+ for(;;)
+ {
+ state_data new_state=old_state;
+ new_state.exclusive=false;
+ new_state.upgrade=true;
+ ++new_state.shared_count;
+ if(new_state.exclusive_waiting)
+ {
+ --new_state.exclusive_waiting;
+ new_state.exclusive_waiting_blocked=false;
+ }
+ new_state.shared_waiting=0;
+
+ state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+ if(current_state==old_state)
+ {
+ break;
+ }
+ old_state=current_state;
+ }
+ release_waiters(old_state);
+ }
+// bool try_unlock_upgrade_and_lock()
+// {
+// return false;
+// }
+//#ifdef BOOST_THREAD_USES_CHRONO
+// template <class Rep, class Period>
+// bool
+// try_unlock_upgrade_and_lock_for(
+// const chrono::duration<Rep, Period>& rel_time)
+// {
+// return try_unlock_upgrade_and_lock_until(
+// chrono::steady_clock::now() + rel_time);
+// }
+// template <class Clock, class Duration>
+// bool
+// try_unlock_upgrade_and_lock_until(
+// const chrono::time_point<Clock, Duration>& abs_time)
+// {
+// return false;
+// }
+//#endif
+
+ void unlock_and_lock_shared()
+ {
+ state_data old_state=state;
+ for(;;)
+ {
+ state_data new_state=old_state;
+ new_state.exclusive=false;
+ ++new_state.shared_count;
+ if(new_state.exclusive_waiting)
+ {
+ --new_state.exclusive_waiting;
+ new_state.exclusive_waiting_blocked=false;
+ }
+ new_state.shared_waiting=0;
+
+ state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+ if(current_state==old_state)
+ {
+ break;
+ }
+ old_state=current_state;
+ }
+ release_waiters(old_state);
+ }
+ void unlock_upgrade_and_lock_shared()
+ {
+ state_data old_state=state;
+ for(;;)
+ {
+ state_data new_state=old_state;
+ new_state.upgrade=false;
+ if(new_state.exclusive_waiting)
+ {
+ --new_state.exclusive_waiting;
+ new_state.exclusive_waiting_blocked=false;
+ }
+ new_state.shared_waiting=0;
+
+ state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+ if(current_state==old_state)
+ {
+ break;
+ }
+ old_state=current_state;
+ }
+ release_waiters(old_state);
+ }
+
+ };
+ typedef shared_mutex upgrade_mutex;
+
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/win32/thread_data.hpp b/src/third_party/boost-1.60.0/boost/thread/win32/thread_data.hpp
new file mode 100644
index 00000000000..005f3ba5035
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/win32/thread_data.hpp
@@ -0,0 +1,328 @@
+#ifndef BOOST_THREAD_PTHREAD_THREAD_DATA_HPP
+#define BOOST_THREAD_PTHREAD_THREAD_DATA_HPP
+// Distributed under the 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 2008 Anthony Williams
+// (C) Copyright 2011-2012 Vicente J. Botet Escriba
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/thread_time.hpp>
+#include <boost/thread/win32/thread_primitives.hpp>
+#include <boost/thread/win32/thread_heap_alloc.hpp>
+
+#include <boost/predef/platform.h>
+
+#include <boost/intrusive_ptr.hpp>
+#ifdef BOOST_THREAD_USES_CHRONO
+#include <boost/chrono/system_clocks.hpp>
+#endif
+
+#include <map>
+#include <vector>
+#include <utility>
+
+#include <boost/config/abi_prefix.hpp>
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4251)
+#endif
+
+namespace boost
+{
+ class condition_variable;
+ class mutex;
+
+ class thread_attributes {
+ public:
+ thread_attributes() BOOST_NOEXCEPT {
+ val_.stack_size = 0;
+ //val_.lpThreadAttributes=0;
+ }
+ ~thread_attributes() {
+ }
+ // stack size
+ void set_stack_size(std::size_t size) BOOST_NOEXCEPT {
+ val_.stack_size = size;
+ }
+
+ std::size_t get_stack_size() const BOOST_NOEXCEPT {
+ return val_.stack_size;
+ }
+
+ //void set_security(LPSECURITY_ATTRIBUTES lpThreadAttributes)
+ //{
+ // val_.lpThreadAttributes=lpThreadAttributes;
+ //}
+ //LPSECURITY_ATTRIBUTES get_security()
+ //{
+ // return val_.lpThreadAttributes;
+ //}
+
+ struct win_attrs {
+ std::size_t stack_size;
+ //LPSECURITY_ATTRIBUTES lpThreadAttributes;
+ };
+ typedef win_attrs native_handle_type;
+ native_handle_type* native_handle() {return &val_;}
+ const native_handle_type* native_handle() const {return &val_;}
+
+ private:
+ win_attrs val_;
+ };
+
+ namespace detail
+ {
+ struct shared_state_base;
+ struct tss_cleanup_function;
+ struct thread_exit_callback_node;
+ struct tss_data_node
+ {
+ boost::shared_ptr<boost::detail::tss_cleanup_function> func;
+ void* value;
+
+ tss_data_node(boost::shared_ptr<boost::detail::tss_cleanup_function> func_,
+ void* value_):
+ func(func_),value(value_)
+ {}
+ };
+
+ struct thread_data_base;
+ void intrusive_ptr_add_ref(thread_data_base * p);
+ void intrusive_ptr_release(thread_data_base * p);
+
+ struct BOOST_THREAD_DECL thread_data_base
+ {
+ long count;
+
+ // Win32 threading APIs are not available in store apps so
+ // use abstraction on top of Windows::System::Threading.
+#if BOOST_PLAT_WINDOWS_RUNTIME
+ detail::win32::scoped_winrt_thread thread_handle;
+#else
+ detail::win32::handle_manager thread_handle;
+#endif
+
+ boost::detail::thread_exit_callback_node* thread_exit_callbacks;
+ unsigned id;
+ std::map<void const*,boost::detail::tss_data_node> tss_data;
+ typedef std::vector<std::pair<condition_variable*, mutex*>
+ //, hidden_allocator<std::pair<condition_variable*, mutex*> >
+ > notify_list_t;
+ notify_list_t notify;
+
+ typedef std::vector<shared_ptr<shared_state_base> > async_states_t;
+ async_states_t async_states_;
+//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ // These data must be at the end so that the access to the other fields doesn't change
+ // when BOOST_THREAD_PROVIDES_INTERRUPTIONS is defined
+ // Another option is to have them always
+ detail::win32::handle_manager interruption_handle;
+ bool interruption_enabled;
+//#endif
+
+ thread_data_base():
+ count(0),
+ thread_handle(),
+ thread_exit_callbacks(0),
+ id(0),
+ tss_data(),
+ notify(),
+ async_states_()
+//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ , interruption_handle(create_anonymous_event(detail::win32::manual_reset_event,detail::win32::event_initially_reset))
+ , interruption_enabled(true)
+//#endif
+ {}
+ virtual ~thread_data_base();
+
+ friend void intrusive_ptr_add_ref(thread_data_base * p)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&p->count);
+ }
+
+ friend void intrusive_ptr_release(thread_data_base * p)
+ {
+ if(!BOOST_INTERLOCKED_DECREMENT(&p->count))
+ {
+ detail::heap_delete(p);
+ }
+ }
+
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ void interrupt()
+ {
+ BOOST_VERIFY(detail::win32::SetEvent(interruption_handle)!=0);
+ }
+#endif
+ typedef detail::win32::handle native_handle_type;
+
+ virtual void run()=0;
+
+ virtual void notify_all_at_thread_exit(condition_variable* cv, mutex* m)
+ {
+ notify.push_back(std::pair<condition_variable*, mutex*>(cv, m));
+ }
+
+ void make_ready_at_thread_exit(shared_ptr<shared_state_base> as)
+ {
+ async_states_.push_back(as);
+ }
+
+ };
+ BOOST_THREAD_DECL thread_data_base* get_current_thread_data();
+
+ typedef boost::intrusive_ptr<detail::thread_data_base> thread_data_ptr;
+
+ struct BOOST_SYMBOL_VISIBLE timeout
+ {
+ win32::ticks_type start;
+ uintmax_t milliseconds;
+ bool relative;
+ boost::system_time abs_time;
+
+ static unsigned long const max_non_infinite_wait=0xfffffffe;
+
+ timeout(uintmax_t milliseconds_):
+ start(win32::GetTickCount64_()()),
+ milliseconds(milliseconds_),
+ relative(true)
+ //,
+ // abs_time(boost::get_system_time())
+ {}
+
+ timeout(boost::system_time const& abs_time_):
+ start(win32::GetTickCount64_()()),
+ milliseconds(0),
+ relative(false),
+ abs_time(abs_time_)
+ {}
+
+ struct BOOST_SYMBOL_VISIBLE remaining_time
+ {
+ bool more;
+ unsigned long milliseconds;
+
+ remaining_time(uintmax_t remaining):
+ more(remaining>max_non_infinite_wait),
+ milliseconds(more?max_non_infinite_wait:(unsigned long)remaining)
+ {}
+ };
+
+ remaining_time remaining_milliseconds() const
+ {
+ if(is_sentinel())
+ {
+ return remaining_time(win32::infinite);
+ }
+ else if(relative)
+ {
+ win32::ticks_type const now=win32::GetTickCount64_()();
+ win32::ticks_type const elapsed=now-start;
+ return remaining_time((elapsed<milliseconds)?(milliseconds-elapsed):0);
+ }
+ else
+ {
+ system_time const now=get_system_time();
+ if(abs_time<=now)
+ {
+ return remaining_time(0);
+ }
+ return remaining_time((abs_time-now).total_milliseconds()+1);
+ }
+ }
+
+ bool is_sentinel() const
+ {
+ return milliseconds==~uintmax_t(0);
+ }
+
+
+ static timeout sentinel()
+ {
+ return timeout(sentinel_type());
+ }
+ private:
+ struct sentinel_type
+ {};
+
+ explicit timeout(sentinel_type):
+ start(0),milliseconds(~uintmax_t(0)),relative(true)
+ {}
+ };
+
+ inline uintmax_t pin_to_zero(intmax_t value)
+ {
+ return (value<0)?0u:(uintmax_t)value;
+ }
+ }
+
+ namespace this_thread
+ {
+ void BOOST_THREAD_DECL yield() BOOST_NOEXCEPT;
+
+ bool BOOST_THREAD_DECL interruptible_wait(detail::win32::handle handle_to_wait_for,detail::timeout target_time);
+ inline void interruptible_wait(uintmax_t milliseconds)
+ {
+ interruptible_wait(detail::win32::invalid_handle_value,milliseconds);
+ }
+ inline BOOST_SYMBOL_VISIBLE void interruptible_wait(system_time const& abs_time)
+ {
+ interruptible_wait(detail::win32::invalid_handle_value,abs_time);
+ }
+ template<typename TimeDuration>
+ inline BOOST_SYMBOL_VISIBLE void sleep(TimeDuration const& rel_time)
+ {
+ interruptible_wait(detail::pin_to_zero(rel_time.total_milliseconds()));
+ }
+ inline BOOST_SYMBOL_VISIBLE void sleep(system_time const& abs_time)
+ {
+ interruptible_wait(abs_time);
+ }
+// #11322 sleep_for() nanoseconds overload will always return too early on windows
+//#ifdef BOOST_THREAD_USES_CHRONO
+// inline void BOOST_SYMBOL_VISIBLE sleep_for(const chrono::nanoseconds& ns)
+// {
+// interruptible_wait(chrono::duration_cast<chrono::milliseconds>(ns).count());
+// }
+//#endif
+ namespace no_interruption_point
+ {
+ bool BOOST_THREAD_DECL non_interruptible_wait(detail::win32::handle handle_to_wait_for,detail::timeout target_time);
+ inline void non_interruptible_wait(uintmax_t milliseconds)
+ {
+ non_interruptible_wait(detail::win32::invalid_handle_value,milliseconds);
+ }
+ inline BOOST_SYMBOL_VISIBLE void non_interruptible_wait(system_time const& abs_time)
+ {
+ non_interruptible_wait(detail::win32::invalid_handle_value,abs_time);
+ }
+ template<typename TimeDuration>
+ inline BOOST_SYMBOL_VISIBLE void sleep(TimeDuration const& rel_time)
+ {
+ non_interruptible_wait(detail::pin_to_zero(rel_time.total_milliseconds()));
+ }
+ inline BOOST_SYMBOL_VISIBLE void sleep(system_time const& abs_time)
+ {
+ non_interruptible_wait(abs_time);
+ }
+// #11322 sleep_for() nanoseconds overload will always return too early on windows
+//#ifdef BOOST_THREAD_USES_CHRONO
+// inline void BOOST_SYMBOL_VISIBLE sleep_for(const chrono::nanoseconds& ns)
+// {
+// non_interruptible_wait(chrono::duration_cast<chrono::milliseconds>(ns).count());
+// }
+//#endif
+ }
+ }
+
+}
+
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/win32/thread_heap_alloc.hpp b/src/third_party/boost-1.60.0/boost/thread/win32/thread_heap_alloc.hpp
new file mode 100644
index 00000000000..610fe3263e1
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/win32/thread_heap_alloc.hpp
@@ -0,0 +1,409 @@
+// Distributed under the 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 2007 Anthony Williams
+#ifndef THREAD_HEAP_ALLOC_HPP
+#define THREAD_HEAP_ALLOC_HPP
+#include <new>
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/win32/thread_primitives.hpp>
+#include <stdexcept>
+#include <boost/assert.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/core/no_exceptions_support.hpp>
+
+#if defined( BOOST_USE_WINDOWS_H )
+# include <windows.h>
+
+namespace boost
+{
+ namespace detail
+ {
+ namespace win32
+ {
+ using ::GetProcessHeap;
+ using ::HeapAlloc;
+ using ::HeapFree;
+ }
+ }
+}
+
+#else
+
+# ifdef HeapAlloc
+# undef HeapAlloc
+# endif
+
+namespace boost
+{
+ namespace detail
+ {
+ namespace win32
+ {
+ extern "C"
+ {
+ __declspec(dllimport) handle __stdcall GetProcessHeap();
+ __declspec(dllimport) void* __stdcall HeapAlloc(handle,unsigned long,ulong_ptr);
+ __declspec(dllimport) int __stdcall HeapFree(handle,unsigned long,void*);
+ }
+ }
+ }
+}
+
+#endif
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ namespace detail
+ {
+ inline void* allocate_raw_heap_memory(unsigned size)
+ {
+ void* const heap_memory=detail::win32::HeapAlloc(detail::win32::GetProcessHeap(),0,size);
+ if(!heap_memory)
+ {
+ boost::throw_exception(std::bad_alloc());
+ }
+ return heap_memory;
+ }
+
+ inline void free_raw_heap_memory(void* heap_memory)
+ {
+ BOOST_VERIFY(detail::win32::HeapFree(detail::win32::GetProcessHeap(),0,heap_memory)!=0);
+ }
+
+ template<typename T>
+ inline T* heap_new()
+ {
+ void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
+ BOOST_TRY
+ {
+ T* const data=new (heap_memory) T();
+ return data;
+ }
+ BOOST_CATCH(...)
+ {
+ free_raw_heap_memory(heap_memory);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ }
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ template<typename T,typename A1>
+ inline T* heap_new(A1&& a1)
+ {
+ void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
+ BOOST_TRY
+ {
+ T* const data=new (heap_memory) T(static_cast<A1&&>(a1));
+ return data;
+ }
+ BOOST_CATCH(...)
+ {
+ free_raw_heap_memory(heap_memory);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ }
+ template<typename T,typename A1,typename A2>
+ inline T* heap_new(A1&& a1,A2&& a2)
+ {
+ void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
+ BOOST_TRY
+ {
+ T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2));
+ return data;
+ }
+ BOOST_CATCH(...)
+ {
+ free_raw_heap_memory(heap_memory);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ }
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1&& a1,A2&& a2,A3&& a3)
+ {
+ void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
+ BOOST_TRY
+ {
+ T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2),
+ static_cast<A3&&>(a3));
+ return data;
+ }
+ BOOST_CATCH(...)
+ {
+ free_raw_heap_memory(heap_memory);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1&& a1,A2&& a2,A3&& a3,A4&& a4)
+ {
+ void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
+ BOOST_TRY
+ {
+ T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2),
+ static_cast<A3&&>(a3),static_cast<A4&&>(a4));
+ return data;
+ }
+ BOOST_CATCH(...)
+ {
+ free_raw_heap_memory(heap_memory);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ }
+#else
+ template<typename T,typename A1>
+ inline T* heap_new_impl(A1 a1)
+ {
+ void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
+ BOOST_TRY
+ {
+ T* const data=new (heap_memory) T(a1);
+ return data;
+ }
+ BOOST_CATCH(...)
+ {
+ free_raw_heap_memory(heap_memory);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ }
+
+ template<typename T,typename A1,typename A2>
+ inline T* heap_new_impl(A1 a1,A2 a2)
+ {
+ void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
+ BOOST_TRY
+ {
+ T* const data=new (heap_memory) T(a1,a2);
+ return data;
+ }
+ BOOST_CATCH(...)
+ {
+ free_raw_heap_memory(heap_memory);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ }
+
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new_impl(A1 a1,A2 a2,A3 a3)
+ {
+ void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
+ BOOST_TRY
+ {
+ T* const data=new (heap_memory) T(a1,a2,a3);
+ return data;
+ }
+ BOOST_CATCH(...)
+ {
+ free_raw_heap_memory(heap_memory);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ }
+
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new_impl(A1 a1,A2 a2,A3 a3,A4 a4)
+ {
+ void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
+ BOOST_TRY
+ {
+ T* const data=new (heap_memory) T(a1,a2,a3,a4);
+ return data;
+ }
+ BOOST_CATCH(...)
+ {
+ free_raw_heap_memory(heap_memory);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ }
+
+
+ template<typename T,typename A1>
+ inline T* heap_new(A1 const& a1)
+ {
+ return heap_new_impl<T,A1 const&>(a1);
+ }
+ template<typename T,typename A1>
+ inline T* heap_new(A1& a1)
+ {
+ return heap_new_impl<T,A1&>(a1);
+ }
+
+ template<typename T,typename A1,typename A2>
+ inline T* heap_new(A1 const& a1,A2 const& a2)
+ {
+ return heap_new_impl<T,A1 const&,A2 const&>(a1,a2);
+ }
+ template<typename T,typename A1,typename A2>
+ inline T* heap_new(A1& a1,A2 const& a2)
+ {
+ return heap_new_impl<T,A1&,A2 const&>(a1,a2);
+ }
+ template<typename T,typename A1,typename A2>
+ inline T* heap_new(A1 const& a1,A2& a2)
+ {
+ return heap_new_impl<T,A1 const&,A2&>(a1,a2);
+ }
+ template<typename T,typename A1,typename A2>
+ inline T* heap_new(A1& a1,A2& a2)
+ {
+ return heap_new_impl<T,A1&,A2&>(a1,a2);
+ }
+
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1 const& a1,A2 const& a2,A3 const& a3)
+ {
+ return heap_new_impl<T,A1 const&,A2 const&,A3 const&>(a1,a2,a3);
+ }
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1& a1,A2 const& a2,A3 const& a3)
+ {
+ return heap_new_impl<T,A1&,A2 const&,A3 const&>(a1,a2,a3);
+ }
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1 const& a1,A2& a2,A3 const& a3)
+ {
+ return heap_new_impl<T,A1 const&,A2&,A3 const&>(a1,a2,a3);
+ }
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1& a1,A2& a2,A3 const& a3)
+ {
+ return heap_new_impl<T,A1&,A2&,A3 const&>(a1,a2,a3);
+ }
+
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1 const& a1,A2 const& a2,A3& a3)
+ {
+ return heap_new_impl<T,A1 const&,A2 const&,A3&>(a1,a2,a3);
+ }
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1& a1,A2 const& a2,A3& a3)
+ {
+ return heap_new_impl<T,A1&,A2 const&,A3&>(a1,a2,a3);
+ }
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1 const& a1,A2& a2,A3& a3)
+ {
+ return heap_new_impl<T,A1 const&,A2&,A3&>(a1,a2,a3);
+ }
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1& a1,A2& a2,A3& a3)
+ {
+ return heap_new_impl<T,A1&,A2&,A3&>(a1,a2,a3);
+ }
+
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2 const& a2,A3 const& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2 const&,A3 const&,A4 const&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2 const& a2,A3 const& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1&,A2 const&,A3 const&,A4 const&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2& a2,A3 const& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2&,A3 const&,A4 const&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2& a2,A3 const& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1&,A2&,A3 const&,A4 const&>(a1,a2,a3,a4);
+ }
+
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2 const& a2,A3& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2 const&,A3&,A4 const&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2 const& a2,A3& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1&,A2 const&,A3&,A4 const&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2& a2,A3& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2&,A3&,A4 const&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2& a2,A3& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1&,A2&,A3&,A4 const&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2 const& a2,A3 const& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2 const&,A3 const&,A4&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2 const& a2,A3 const& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1&,A2 const&,A3 const&,A4&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2& a2,A3 const& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2&,A3 const&,A4&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2& a2,A3 const& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1&,A2&,A3 const&,A4&>(a1,a2,a3,a4);
+ }
+
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2 const& a2,A3& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2 const&,A3&,A4&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2 const& a2,A3& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1&,A2 const&,A3&,A4&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2& a2,A3& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2&,A3&,A4&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2& a2,A3& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1&,A2&,A3&,A4&>(a1,a2,a3,a4);
+ }
+
+#endif
+ template<typename T>
+ inline void heap_delete(T* data)
+ {
+ data->~T();
+ free_raw_heap_memory(data);
+ }
+
+ template<typename T>
+ struct do_heap_delete
+ {
+ void operator()(T* data) const
+ {
+ detail::heap_delete(data);
+ }
+ };
+ }
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/win32/thread_primitives.hpp b/src/third_party/boost-1.60.0/boost/thread/win32/thread_primitives.hpp
new file mode 100644
index 00000000000..b63503ad52b
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/win32/thread_primitives.hpp
@@ -0,0 +1,669 @@
+#ifndef BOOST_WIN32_THREAD_PRIMITIVES_HPP
+#define BOOST_WIN32_THREAD_PRIMITIVES_HPP
+
+// win32_thread_primitives.hpp
+//
+// (C) Copyright 2005-7 Anthony Williams
+// (C) Copyright 2007 David Deakins
+//
+// Distributed under the 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/detail/config.hpp>
+#include <boost/predef/platform.h>
+#include <boost/throw_exception.hpp>
+#include <boost/assert.hpp>
+#include <boost/thread/exceptions.hpp>
+#include <boost/detail/interlocked.hpp>
+//#include <boost/detail/winapi/synchronization.hpp>
+#include <algorithm>
+
+#if BOOST_PLAT_WINDOWS_RUNTIME
+#include <thread>
+#endif
+
+#if defined( BOOST_USE_WINDOWS_H )
+# include <windows.h>
+
+namespace boost
+{
+ namespace detail
+ {
+ namespace win32
+ {
+ typedef HANDLE handle;
+ typedef SYSTEM_INFO system_info;
+ typedef unsigned __int64 ticks_type;
+ typedef FARPROC farproc_t;
+ unsigned const infinite=INFINITE;
+ unsigned const timeout=WAIT_TIMEOUT;
+ handle const invalid_handle_value=INVALID_HANDLE_VALUE;
+ unsigned const event_modify_state=EVENT_MODIFY_STATE;
+ unsigned const synchronize=SYNCHRONIZE;
+ unsigned const wait_abandoned=WAIT_ABANDONED;
+ unsigned const create_event_initial_set = 0x00000002;
+ unsigned const create_event_manual_reset = 0x00000001;
+ unsigned const event_all_access = EVENT_ALL_ACCESS;
+ unsigned const semaphore_all_access = SEMAPHORE_ALL_ACCESS;
+
+
+# ifdef BOOST_NO_ANSI_APIS
+# if BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA
+ using ::CreateMutexW;
+ using ::CreateEventW;
+ using ::CreateSemaphoreW;
+# else
+ using ::CreateMutexExW;
+ using ::CreateEventExW;
+ using ::CreateSemaphoreExW;
+# endif
+ using ::OpenEventW;
+ using ::GetModuleHandleW;
+# else
+ using ::CreateMutexA;
+ using ::CreateEventA;
+ using ::OpenEventA;
+ using ::CreateSemaphoreA;
+ using ::GetModuleHandleA;
+# endif
+#if BOOST_PLAT_WINDOWS_RUNTIME
+ using ::GetNativeSystemInfo;
+ using ::GetTickCount64;
+#else
+ using ::GetSystemInfo;
+ using ::GetTickCount;
+#endif
+ using ::CloseHandle;
+ using ::ReleaseMutex;
+ using ::ReleaseSemaphore;
+ using ::SetEvent;
+ using ::ResetEvent;
+ using ::WaitForMultipleObjectsEx;
+ using ::WaitForSingleObjectEx;
+ using ::GetCurrentProcessId;
+ using ::GetCurrentThreadId;
+ using ::GetCurrentThread;
+ using ::GetCurrentProcess;
+ using ::DuplicateHandle;
+#if !BOOST_PLAT_WINDOWS_RUNTIME
+ using ::SleepEx;
+ using ::Sleep;
+ using ::QueueUserAPC;
+ using ::GetProcAddress;
+#endif
+ }
+ }
+}
+#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ )
+
+# ifdef UNDER_CE
+# ifndef WINAPI
+# ifndef _WIN32_WCE_EMULATION
+# define WINAPI __cdecl // Note this doesn't match the desktop definition
+# else
+# define WINAPI __stdcall
+# endif
+# endif
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+typedef int BOOL;
+typedef unsigned long DWORD;
+typedef void* HANDLE;
+# include <kfuncs.h>
+# ifdef __cplusplus
+}
+# endif
+# endif
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+struct _SYSTEM_INFO;
+# ifdef __cplusplus
+}
+#endif
+
+namespace boost
+{
+ namespace detail
+ {
+ namespace win32
+ {
+# ifdef _WIN64
+ typedef unsigned __int64 ulong_ptr;
+# else
+ typedef unsigned long ulong_ptr;
+# endif
+ typedef void* handle;
+ typedef _SYSTEM_INFO system_info;
+ typedef unsigned __int64 ticks_type;
+ typedef int (__stdcall *farproc_t)();
+ unsigned const infinite=~0U;
+ unsigned const timeout=258U;
+ handle const invalid_handle_value=(handle)(-1);
+ unsigned const event_modify_state=2;
+ unsigned const synchronize=0x100000u;
+ unsigned const wait_abandoned=0x00000080u;
+ unsigned const create_event_initial_set = 0x00000002;
+ unsigned const create_event_manual_reset = 0x00000001;
+ unsigned const event_all_access = 0x1F0003;
+ unsigned const semaphore_all_access = 0x1F0003;
+
+ extern "C"
+ {
+ struct _SECURITY_ATTRIBUTES;
+# ifdef BOOST_NO_ANSI_APIS
+# if BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA
+ __declspec(dllimport) void* __stdcall CreateMutexW(_SECURITY_ATTRIBUTES*,int,wchar_t const*);
+ __declspec(dllimport) void* __stdcall CreateSemaphoreW(_SECURITY_ATTRIBUTES*,long,long,wchar_t const*);
+ __declspec(dllimport) void* __stdcall CreateEventW(_SECURITY_ATTRIBUTES*,int,int,wchar_t const*);
+# else
+ __declspec(dllimport) void* __stdcall CreateMutexExW(_SECURITY_ATTRIBUTES*,wchar_t const*,unsigned long,unsigned long);
+ __declspec(dllimport) void* __stdcall CreateEventExW(_SECURITY_ATTRIBUTES*,wchar_t const*,unsigned long,unsigned long);
+ __declspec(dllimport) void* __stdcall CreateSemaphoreExW(_SECURITY_ATTRIBUTES*,long,long,wchar_t const*,unsigned long,unsigned long);
+# endif
+ __declspec(dllimport) void* __stdcall OpenEventW(unsigned long,int,wchar_t const*);
+ __declspec(dllimport) void* __stdcall GetModuleHandleW(wchar_t const*);
+# else
+ __declspec(dllimport) void* __stdcall CreateMutexA(_SECURITY_ATTRIBUTES*,int,char const*);
+ __declspec(dllimport) void* __stdcall CreateSemaphoreA(_SECURITY_ATTRIBUTES*,long,long,char const*);
+ __declspec(dllimport) void* __stdcall CreateEventA(_SECURITY_ATTRIBUTES*,int,int,char const*);
+ __declspec(dllimport) void* __stdcall OpenEventA(unsigned long,int,char const*);
+ __declspec(dllimport) void* __stdcall GetModuleHandleA(char const*);
+# endif
+#if BOOST_PLAT_WINDOWS_RUNTIME
+ __declspec(dllimport) void __stdcall GetNativeSystemInfo(_SYSTEM_INFO*);
+ __declspec(dllimport) ticks_type __stdcall GetTickCount64();
+#else
+ __declspec(dllimport) void __stdcall GetSystemInfo(_SYSTEM_INFO*);
+ __declspec(dllimport) unsigned long __stdcall GetTickCount();
+#endif
+ __declspec(dllimport) int __stdcall CloseHandle(void*);
+ __declspec(dllimport) int __stdcall ReleaseMutex(void*);
+ __declspec(dllimport) unsigned long __stdcall WaitForSingleObjectEx(void*,unsigned long,int);
+ __declspec(dllimport) unsigned long __stdcall WaitForMultipleObjectsEx(unsigned long nCount,void* const * lpHandles,int bWaitAll,unsigned long dwMilliseconds,int bAlertable);
+ __declspec(dllimport) int __stdcall ReleaseSemaphore(void*,long,long*);
+ __declspec(dllimport) int __stdcall DuplicateHandle(void*,void*,void*,void**,unsigned long,int,unsigned long);
+#if !BOOST_PLAT_WINDOWS_RUNTIME
+ __declspec(dllimport) unsigned long __stdcall SleepEx(unsigned long,int);
+ __declspec(dllimport) void __stdcall Sleep(unsigned long);
+ typedef void (__stdcall *queue_user_apc_callback_function)(ulong_ptr);
+ __declspec(dllimport) unsigned long __stdcall QueueUserAPC(queue_user_apc_callback_function,void*,ulong_ptr);
+ __declspec(dllimport) farproc_t __stdcall GetProcAddress(void *, const char *);
+#endif
+
+# ifndef UNDER_CE
+ __declspec(dllimport) unsigned long __stdcall GetCurrentProcessId();
+ __declspec(dllimport) unsigned long __stdcall GetCurrentThreadId();
+ __declspec(dllimport) void* __stdcall GetCurrentThread();
+ __declspec(dllimport) void* __stdcall GetCurrentProcess();
+ __declspec(dllimport) int __stdcall SetEvent(void*);
+ __declspec(dllimport) int __stdcall ResetEvent(void*);
+# else
+ using ::GetCurrentProcessId;
+ using ::GetCurrentThreadId;
+ using ::GetCurrentThread;
+ using ::GetCurrentProcess;
+ using ::SetEvent;
+ using ::ResetEvent;
+# endif
+ }
+ }
+ }
+}
+#else
+# error "Win32 functions not available"
+#endif
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ namespace detail
+ {
+ namespace win32
+ {
+ namespace detail { typedef ticks_type (__stdcall *gettickcount64_t)(); }
+#if !BOOST_PLAT_WINDOWS_RUNTIME
+ extern "C"
+ {
+#ifdef _MSC_VER
+ long _InterlockedCompareExchange(long volatile *, long, long);
+#pragma intrinsic(_InterlockedCompareExchange)
+#elif defined(__MINGW64_VERSION_MAJOR)
+ long _InterlockedCompareExchange(long volatile *, long, long);
+#else
+ // Mingw doesn't provide intrinsics
+#define _InterlockedCompareExchange InterlockedCompareExchange
+#endif
+ }
+ // Borrowed from https://stackoverflow.com/questions/8211820/userland-interrupt-timer-access-such-as-via-kequeryinterrupttime-or-similar
+ inline ticks_type __stdcall GetTickCount64emulation()
+ {
+ static volatile long count = 0xFFFFFFFF;
+ unsigned long previous_count, current_tick32, previous_count_zone, current_tick32_zone;
+ ticks_type current_tick64;
+
+ previous_count = (unsigned long) _InterlockedCompareExchange(&count, 0, 0);
+ current_tick32 = GetTickCount();
+
+ if(previous_count == 0xFFFFFFFF)
+ {
+ // count has never been written
+ unsigned long initial_count;
+ initial_count = current_tick32 >> 28;
+ previous_count = (unsigned long) _InterlockedCompareExchange(&count, initial_count, 0xFFFFFFFF);
+
+ current_tick64 = initial_count;
+ current_tick64 <<= 28;
+ current_tick64 += current_tick32 & 0x0FFFFFFF;
+ return current_tick64;
+ }
+
+ previous_count_zone = previous_count & 15;
+ current_tick32_zone = current_tick32 >> 28;
+
+ if(current_tick32_zone == previous_count_zone)
+ {
+ // The top four bits of the 32-bit tick count haven't changed since count was last written.
+ current_tick64 = previous_count;
+ current_tick64 <<= 28;
+ current_tick64 += current_tick32 & 0x0FFFFFFF;
+ return current_tick64;
+ }
+
+ if(current_tick32_zone == previous_count_zone + 1 || (current_tick32_zone == 0 && previous_count_zone == 15))
+ {
+ // The top four bits of the 32-bit tick count have been incremented since count was last written.
+ _InterlockedCompareExchange(&count, previous_count + 1, previous_count);
+ current_tick64 = previous_count + 1;
+ current_tick64 <<= 28;
+ current_tick64 += current_tick32 & 0x0FFFFFFF;
+ return current_tick64;
+ }
+
+ // Oops, we weren't called often enough, we're stuck
+ return 0xFFFFFFFF;
+ }
+#else
+#endif
+ inline detail::gettickcount64_t GetTickCount64_()
+ {
+ static detail::gettickcount64_t gettickcount64impl;
+ if(gettickcount64impl)
+ return gettickcount64impl;
+
+ // GetTickCount and GetModuleHandle are not allowed in the Windows Runtime,
+ // and kernel32 isn't used in Windows Phone.
+#if BOOST_PLAT_WINDOWS_RUNTIME
+ gettickcount64impl = &GetTickCount64;
+#else
+ farproc_t addr=GetProcAddress(
+#if !defined(BOOST_NO_ANSI_APIS)
+ GetModuleHandleA("KERNEL32.DLL"),
+#else
+ GetModuleHandleW(L"KERNEL32.DLL"),
+#endif
+ "GetTickCount64");
+ if(addr)
+ gettickcount64impl=(detail::gettickcount64_t) addr;
+ else
+ gettickcount64impl=&GetTickCount64emulation;
+#endif
+ return gettickcount64impl;
+ }
+
+ enum event_type
+ {
+ auto_reset_event=false,
+ manual_reset_event=true
+ };
+
+ enum initial_event_state
+ {
+ event_initially_reset=false,
+ event_initially_set=true
+ };
+
+ inline handle create_event(
+#if !defined(BOOST_NO_ANSI_APIS)
+ const char *mutex_name,
+#else
+ const wchar_t *mutex_name,
+#endif
+ event_type type,
+ initial_event_state state)
+ {
+#if !defined(BOOST_NO_ANSI_APIS)
+ handle const res = win32::CreateEventA(0, type, state, mutex_name);
+#elif BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA
+ handle const res = win32::CreateEventW(0, type, state, mutex_name);
+#else
+ handle const res = win32::CreateEventExW(
+ 0,
+ mutex_name,
+ type ? create_event_manual_reset : 0 | state ? create_event_initial_set : 0,
+ event_all_access);
+#endif
+ return res;
+ }
+
+ inline handle create_anonymous_event(event_type type,initial_event_state state)
+ {
+ handle const res = create_event(0, type, state);
+ if(!res)
+ {
+ boost::throw_exception(thread_resource_error());
+ }
+ return res;
+ }
+
+ inline handle create_anonymous_semaphore_nothrow(long initial_count,long max_count)
+ {
+#if !defined(BOOST_NO_ANSI_APIS)
+ handle const res=win32::CreateSemaphoreA(0,initial_count,max_count,0);
+#else
+#if BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA
+ handle const res=win32::CreateSemaphoreEx(0,initial_count,max_count,0,0);
+#else
+ handle const res=win32::CreateSemaphoreExW(0,initial_count,max_count,0,0,semaphore_all_access);
+#endif
+#endif
+ return res;
+ }
+
+ inline handle create_anonymous_semaphore(long initial_count,long max_count)
+ {
+ handle const res=create_anonymous_semaphore_nothrow(initial_count,max_count);
+ if(!res)
+ {
+ boost::throw_exception(thread_resource_error());
+ }
+ return res;
+ }
+
+ inline handle duplicate_handle(handle source)
+ {
+ handle const current_process=GetCurrentProcess();
+ long const same_access_flag=2;
+ handle new_handle=0;
+ bool const success=DuplicateHandle(current_process,source,current_process,&new_handle,0,false,same_access_flag)!=0;
+ if(!success)
+ {
+ boost::throw_exception(thread_resource_error());
+ }
+ return new_handle;
+ }
+
+ inline void release_semaphore(handle semaphore,long count)
+ {
+ BOOST_VERIFY(ReleaseSemaphore(semaphore,count,0)!=0);
+ }
+
+ inline void get_system_info(system_info *info)
+ {
+#if BOOST_PLAT_WINDOWS_RUNTIME
+ win32::GetNativeSystemInfo(info);
+#else
+ win32::GetSystemInfo(info);
+#endif
+ }
+
+ inline void sleep(unsigned long milliseconds)
+ {
+ if(milliseconds == 0)
+ {
+#if BOOST_PLAT_WINDOWS_RUNTIME
+ std::this_thread::yield();
+#else
+ ::boost::detail::win32::Sleep(0);
+#endif
+ }
+ else
+ {
+#if BOOST_PLAT_WINDOWS_RUNTIME
+ ::boost::detail::win32::WaitForSingleObjectEx(::boost::detail::win32::GetCurrentThread(), milliseconds, 0);
+#else
+ ::boost::detail::win32::Sleep(milliseconds);
+#endif
+ }
+ }
+
+#if BOOST_PLAT_WINDOWS_RUNTIME
+ class BOOST_THREAD_DECL scoped_winrt_thread
+ {
+ public:
+ scoped_winrt_thread() : m_completionHandle(invalid_handle_value)
+ {}
+
+ ~scoped_winrt_thread()
+ {
+ if (m_completionHandle != ::boost::detail::win32::invalid_handle_value)
+ {
+ CloseHandle(m_completionHandle);
+ }
+ }
+
+ typedef unsigned(__stdcall * thread_func)(void *);
+ bool start(thread_func address, void *parameter, unsigned int *thrdId);
+
+ handle waitable_handle() const
+ {
+ BOOST_ASSERT(m_completionHandle != ::boost::detail::win32::invalid_handle_value);
+ return m_completionHandle;
+ }
+
+ private:
+ handle m_completionHandle;
+ };
+#endif
+ class BOOST_THREAD_DECL handle_manager
+ {
+ private:
+ handle handle_to_manage;
+ handle_manager(handle_manager&);
+ handle_manager& operator=(handle_manager&);
+
+ void cleanup()
+ {
+ if(handle_to_manage && handle_to_manage!=invalid_handle_value)
+ {
+ BOOST_VERIFY(CloseHandle(handle_to_manage));
+ }
+ }
+
+ public:
+ explicit handle_manager(handle handle_to_manage_):
+ handle_to_manage(handle_to_manage_)
+ {}
+ handle_manager():
+ handle_to_manage(0)
+ {}
+
+ handle_manager& operator=(handle new_handle)
+ {
+ cleanup();
+ handle_to_manage=new_handle;
+ return *this;
+ }
+
+ operator handle() const
+ {
+ return handle_to_manage;
+ }
+
+ handle duplicate() const
+ {
+ return duplicate_handle(handle_to_manage);
+ }
+
+ void swap(handle_manager& other)
+ {
+ std::swap(handle_to_manage,other.handle_to_manage);
+ }
+
+ handle release()
+ {
+ handle const res=handle_to_manage;
+ handle_to_manage=0;
+ return res;
+ }
+
+ bool operator!() const
+ {
+ return !handle_to_manage;
+ }
+
+ ~handle_manager()
+ {
+ cleanup();
+ }
+ };
+ }
+ }
+}
+
+#if defined(BOOST_MSVC) && (_MSC_VER>=1400) && !defined(UNDER_CE)
+
+namespace boost
+{
+ namespace detail
+ {
+ namespace win32
+ {
+#if _MSC_VER==1400
+ extern "C" unsigned char _interlockedbittestandset(long *a,long b);
+ extern "C" unsigned char _interlockedbittestandreset(long *a,long b);
+#else
+ extern "C" unsigned char _interlockedbittestandset(volatile long *a,long b);
+ extern "C" unsigned char _interlockedbittestandreset(volatile long *a,long b);
+#endif
+
+#pragma intrinsic(_interlockedbittestandset)
+#pragma intrinsic(_interlockedbittestandreset)
+
+ inline bool interlocked_bit_test_and_set(long* x,long bit)
+ {
+ return _interlockedbittestandset(x,bit)!=0;
+ }
+
+ inline bool interlocked_bit_test_and_reset(long* x,long bit)
+ {
+ return _interlockedbittestandreset(x,bit)!=0;
+ }
+
+ }
+ }
+}
+#define BOOST_THREAD_BTS_DEFINED
+#elif (defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN)) && defined(_M_IX86)
+namespace boost
+{
+ namespace detail
+ {
+ namespace win32
+ {
+ inline bool interlocked_bit_test_and_set(long* x,long bit)
+ {
+#ifndef BOOST_INTEL_CXX_VERSION
+ __asm {
+ mov eax,bit;
+ mov edx,x;
+ lock bts [edx],eax;
+ setc al;
+ };
+#else
+ bool ret;
+ __asm {
+ mov eax,bit
+ mov edx,x
+ lock bts [edx],eax
+ setc al
+ mov ret, al
+ };
+ return ret;
+
+#endif
+ }
+
+ inline bool interlocked_bit_test_and_reset(long* x,long bit)
+ {
+#ifndef BOOST_INTEL_CXX_VERSION
+ __asm {
+ mov eax,bit;
+ mov edx,x;
+ lock btr [edx],eax;
+ setc al;
+ };
+#else
+ bool ret;
+ __asm {
+ mov eax,bit
+ mov edx,x
+ lock btr [edx],eax
+ setc al
+ mov ret, al
+ };
+ return ret;
+
+#endif
+ }
+
+ }
+ }
+}
+#define BOOST_THREAD_BTS_DEFINED
+#endif
+
+#ifndef BOOST_THREAD_BTS_DEFINED
+
+namespace boost
+{
+ namespace detail
+ {
+ namespace win32
+ {
+ inline bool interlocked_bit_test_and_set(long* x,long bit)
+ {
+ long const value=1<<bit;
+ long old=*x;
+ do
+ {
+ long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,old|value,old);
+ if(current==old)
+ {
+ break;
+ }
+ old=current;
+ }
+ while(true) ;
+ return (old&value)!=0;
+ }
+
+ inline bool interlocked_bit_test_and_reset(long* x,long bit)
+ {
+ long const value=1<<bit;
+ long old=*x;
+ do
+ {
+ long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,old&~value,old);
+ if(current==old)
+ {
+ break;
+ }
+ old=current;
+ }
+ while(true) ;
+ return (old&value)!=0;
+ }
+ }
+ }
+}
+#endif
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.60.0/boost/thread/with_lock_guard.hpp b/src/third_party/boost-1.60.0/boost/thread/with_lock_guard.hpp
new file mode 100644
index 00000000000..5d99b36f2e4
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/with_lock_guard.hpp
@@ -0,0 +1,234 @@
+// (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.
+
+#ifndef BOOST_THREAD_WITH_LOCK_GUARD_HPP
+#define BOOST_THREAD_WITH_LOCK_GUARD_HPP
+
+#include <boost/thread/lock_guard.hpp>
+#include <boost/utility/result_of.hpp>
+//#include <boost/thread/detail/invoke.hpp>
+
+namespace boost {
+
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
+ !defined(BOOST_NO_CXX11_DECLTYPE) && \
+ !defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES)
+
+/**
+ * Utility to run functions in scope protected by mutex.
+ *
+ * Examples:
+ *
+ * int func(int, int&);
+ * boost::mutex m;
+ * int a;
+ * int result = boost::with_lock_guard(m, func, 1, boost::ref(a));
+ *
+ * // using boost::bind
+ * int result = boost::with_lock_guard(
+ * m, boost::bind(func, 2, boost::ref(a))
+ * );
+ *
+ * // using lambda
+ * int a;
+ * int result = boost::with_lock_guard(
+ * m,
+ * [&a](int x) {
+ * a = 3;
+ * return x + 4;
+ * },
+ * 5
+ * );
+ */
+template <class Lockable, class Function, class... Args>
+typename boost::result_of<Function(Args...)>::type with_lock_guard(
+ Lockable& m,
+ BOOST_FWD_REF(Function) func,
+ BOOST_FWD_REF(Args)... args
+) //-> decltype(func(boost::forward<Args>(args)...))
+{
+ boost::lock_guard<Lockable> lock(m);
+ return func(boost::forward<Args>(args)...);
+}
+
+#else
+
+// Workaround versions for compilers without c++11 variadic templates support.
+// (function arguments limit: 4)
+// (for lambda support define BOOST_RESULT_OF_USE_DECLTYPE may be needed)
+
+template <class Lockable, class Func>
+typename boost::result_of<Func()>::type with_lock_guard(
+ Lockable& m,
+ BOOST_FWD_REF(Func) func
+) {
+ boost::lock_guard<Lockable> lock(m);
+ return func();
+}
+
+template <class Lockable, class Func, class Arg>
+typename boost::result_of<Func(Arg)>::type with_lock_guard(
+ Lockable& m,
+ BOOST_FWD_REF(Func) func,
+ BOOST_FWD_REF(Arg) arg
+) {
+ boost::lock_guard<Lockable> lock(m);
+ return func(
+ boost::forward<Arg>(arg)
+ );
+}
+
+template <class Lockable, class Func, class Arg1, class Arg2>
+typename boost::result_of<Func(Arg1, Arg2)>::type with_lock_guard(
+ Lockable& m,
+ BOOST_FWD_REF(Func) func,
+ BOOST_FWD_REF(Arg1) arg1,
+ BOOST_FWD_REF(Arg2) arg2
+) {
+ boost::lock_guard<Lockable> lock(m);
+ return func(
+ boost::forward<Arg1>(arg1),
+ boost::forward<Arg2>(arg2)
+ );
+}
+
+template <class Lockable, class Func, class Arg1, class Arg2, class Arg3>
+typename boost::result_of<Func(Arg1, Arg2, Arg3)>::type with_lock_guard(
+ Lockable& m,
+ BOOST_FWD_REF(Func) func,
+ BOOST_FWD_REF(Arg1) arg1,
+ BOOST_FWD_REF(Arg2) arg2,
+ BOOST_FWD_REF(Arg3) arg3
+) {
+ boost::lock_guard<Lockable> lock(m);
+ return func(
+ boost::forward<Arg1>(arg1),
+ boost::forward<Arg2>(arg2),
+ boost::forward<Arg3>(arg3)
+ );
+}
+
+template <
+ class Lockable, class Func, class Arg1, class Arg2, class Arg3, class Arg4
+>
+typename boost::result_of<Func(Arg1, Arg2, Arg3, Arg4)>::type with_lock_guard(
+ Lockable& m,
+ BOOST_FWD_REF(Func) func,
+ BOOST_FWD_REF(Arg1) arg1,
+ BOOST_FWD_REF(Arg2) arg2,
+ BOOST_FWD_REF(Arg3) arg3,
+ BOOST_FWD_REF(Arg4) arg4
+) {
+ boost::lock_guard<Lockable> lock(m);
+ return func(
+ boost::forward<Arg1>(arg1),
+ boost::forward<Arg2>(arg2),
+ boost::forward<Arg3>(arg3),
+ boost::forward<Arg4>(arg4)
+ );
+}
+
+// overloads for function pointer
+// (if argument is not function pointer, static assert will trigger)
+template <class Lockable, class Func>
+typename boost::result_of<
+ typename boost::add_pointer<Func>::type()
+>::type with_lock_guard(
+ Lockable& m,
+ Func* func
+) {
+ BOOST_STATIC_ASSERT(boost::is_function<Func>::value);
+
+ boost::lock_guard<Lockable> lock(m);
+ return func();
+}
+
+template <class Lockable, class Func, class Arg>
+typename boost::result_of<
+ typename boost::add_pointer<Func>::type(Arg)
+>::type with_lock_guard(
+ Lockable& m,
+ Func* func,
+ BOOST_FWD_REF(Arg) arg
+) {
+ BOOST_STATIC_ASSERT(boost::is_function<Func>::value);
+
+ boost::lock_guard<Lockable> lock(m);
+ return func(
+ boost::forward<Arg>(arg)
+ );
+}
+
+template <class Lockable, class Func, class Arg1, class Arg2>
+typename boost::result_of<
+ typename boost::add_pointer<Func>::type(Arg1, Arg2)
+>::type with_lock_guard(
+ Lockable& m,
+ Func* func,
+ BOOST_FWD_REF(Arg1) arg1,
+ BOOST_FWD_REF(Arg2) arg2
+) {
+ BOOST_STATIC_ASSERT(boost::is_function<Func>::value);
+
+ boost::lock_guard<Lockable> lock(m);
+ return func(
+ boost::forward<Arg1>(arg1),
+ boost::forward<Arg2>(arg2)
+ );
+}
+
+template <class Lockable, class Func, class Arg1, class Arg2, class Arg3>
+typename boost::result_of<
+ typename boost::add_pointer<Func>::type(Arg1, Arg2, Arg3)
+>::type with_lock_guard(
+ Lockable& m,
+ Func* func,
+ BOOST_FWD_REF(Arg1) arg1,
+ BOOST_FWD_REF(Arg2) arg2,
+ BOOST_FWD_REF(Arg3) arg3
+) {
+ BOOST_STATIC_ASSERT(boost::is_function<Func>::value);
+
+ boost::lock_guard<Lockable> lock(m);
+ return func(
+ boost::forward<Arg1>(arg1),
+ boost::forward<Arg2>(arg2),
+ boost::forward<Arg3>(arg3)
+ );
+}
+
+template <
+ class Lockable, class Func, class Arg1, class Arg2, class Arg3, class Arg4
+>
+typename boost::result_of<
+ typename boost::add_pointer<Func>::type(Arg1, Arg2, Arg3, Arg4)
+>::type with_lock_guard(
+ Lockable& m,
+ Func* func,
+ BOOST_FWD_REF(Arg1) arg1,
+ BOOST_FWD_REF(Arg2) arg2,
+ BOOST_FWD_REF(Arg3) arg3,
+ BOOST_FWD_REF(Arg4) arg4
+) {
+ BOOST_STATIC_ASSERT(boost::is_function<Func>::value);
+
+ boost::lock_guard<Lockable> lock(m);
+ return func(
+ boost::forward<Arg1>(arg1),
+ boost::forward<Arg2>(arg2),
+ boost::forward<Arg3>(arg3),
+ boost::forward<Arg4>(arg4)
+ );
+}
+
+#endif
+
+} // namespace boost
+
+#endif // BOOST_THREAD_WITH_LOCK_GUARD_HPP
+
diff --git a/src/third_party/boost-1.60.0/boost/thread/xtime.hpp b/src/third_party/boost-1.60.0/boost/thread/xtime.hpp
new file mode 100644
index 00000000000..9c6a3596400
--- /dev/null
+++ b/src/third_party/boost-1.60.0/boost/thread/xtime.hpp
@@ -0,0 +1,93 @@
+// 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)
+
+#ifndef BOOST_XTIME_WEK070601_HPP
+#define BOOST_XTIME_WEK070601_HPP
+
+#include <boost/thread/detail/config.hpp>
+#if defined BOOST_THREAD_USES_DATETIME
+
+#include <boost/cstdint.hpp>
+#include <boost/thread/thread_time.hpp>
+#include <boost/date_time/posix_time/conversion.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost {
+
+enum xtime_clock_types
+{
+ TIME_UTC_=1
+// TIME_TAI,
+// TIME_MONOTONIC,
+// TIME_PROCESS,
+// TIME_THREAD,
+// TIME_LOCAL,
+// TIME_SYNC,
+// TIME_RESOLUTION
+};
+
+struct xtime
+{
+#if defined(BOOST_NO_INT64_T)
+ typedef int_fast32_t xtime_sec_t; //INT_FAST32_MIN <= sec <= INT_FAST32_MAX
+#else
+ typedef int_fast64_t xtime_sec_t; //INT_FAST64_MIN <= sec <= INT_FAST64_MAX
+#endif
+
+ typedef int_fast32_t xtime_nsec_t; //0 <= xtime.nsec < NANOSECONDS_PER_SECOND
+
+ xtime_sec_t sec;
+ xtime_nsec_t nsec;
+
+ operator system_time() const
+ {
+ return boost::posix_time::from_time_t(0)+
+ boost::posix_time::seconds(static_cast<long>(sec))+
+#ifdef BOOST_DATE_TIME_HAS_NANOSECONDS
+ boost::posix_time::nanoseconds(nsec);
+#else
+ boost::posix_time::microseconds((nsec+500)/1000);
+#endif
+ }
+
+};
+
+inline xtime get_xtime(boost::system_time const& abs_time)
+{
+ xtime res;
+ boost::posix_time::time_duration const time_since_epoch=abs_time-boost::posix_time::from_time_t(0);
+
+ res.sec=static_cast<xtime::xtime_sec_t>(time_since_epoch.total_seconds());
+ res.nsec=static_cast<xtime::xtime_nsec_t>(time_since_epoch.fractional_seconds()*(1000000000/time_since_epoch.ticks_per_second()));
+ return res;
+}
+
+inline int xtime_get(struct xtime* xtp, int clock_type)
+{
+ if (clock_type == TIME_UTC_)
+ {
+ *xtp=get_xtime(get_system_time());
+ return clock_type;
+ }
+ return 0;
+}
+
+
+inline int xtime_cmp(const xtime& xt1, const xtime& xt2)
+{
+ if (xt1.sec == xt2.sec)
+ return (int)(xt1.nsec - xt2.nsec);
+ else
+ return (xt1.sec > xt2.sec) ? 1 : -1;
+}
+
+} // namespace boost
+
+#include <boost/config/abi_suffix.hpp>
+#endif
+#endif //BOOST_XTIME_WEK070601_HPP