summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Markmann <tm@ayena.de>2014-10-19 20:22:58 (GMT)
committerTobias Markmann <tm@ayena.de>2014-10-20 13:49:33 (GMT)
commit6b22dfcf59474dd016a0355a3102a1dd3692d92c (patch)
tree2b1fd33be433a91e81fee84fdc2bf1b52575d934 /3rdParty/Boost/src/boost/thread
parent38b0cb785fea8eae5e48fae56440695fdfd10ee1 (diff)
downloadswift-6b22dfcf59474dd016a0355a3102a1dd3692d92c.zip
swift-6b22dfcf59474dd016a0355a3102a1dd3692d92c.tar.bz2
Update Boost in 3rdParty to version 1.56.0.
This updates Boost in our 3rdParty directory to version 1.56.0. Updated our update.sh script to stop on error. Changed error reporting in SwiftTools/CrashReporter.cpp to SWIFT_LOG due to missing include of <iostream> with newer Boost. Change-Id: I4b35c77de951333979a524097f35f5f83d325edc
Diffstat (limited to '3rdParty/Boost/src/boost/thread')
-rw-r--r--3rdParty/Boost/src/boost/thread/barrier.hpp252
-rw-r--r--3rdParty/Boost/src/boost/thread/csbl/memory/allocator_arg.hpp41
-rw-r--r--3rdParty/Boost/src/boost/thread/csbl/memory/allocator_traits.hpp35
-rw-r--r--3rdParty/Boost/src/boost/thread/csbl/memory/config.hpp16
-rw-r--r--3rdParty/Boost/src/boost/thread/csbl/memory/pointer_traits.hpp35
-rw-r--r--3rdParty/Boost/src/boost/thread/csbl/memory/scoped_allocator.hpp35
-rw-r--r--3rdParty/Boost/src/boost/thread/csbl/tuple.hpp45
-rw-r--r--3rdParty/Boost/src/boost/thread/csbl/vector.hpp35
-rw-r--r--3rdParty/Boost/src/boost/thread/cv_status.hpp2
-rw-r--r--3rdParty/Boost/src/boost/thread/detail/config.hpp313
-rw-r--r--3rdParty/Boost/src/boost/thread/detail/delete.hpp13
-rw-r--r--3rdParty/Boost/src/boost/thread/detail/invoke.hpp1606
-rw-r--r--3rdParty/Boost/src/boost/thread/detail/invoker.hpp738
-rw-r--r--3rdParty/Boost/src/boost/thread/detail/is_convertible.hpp49
-rw-r--r--3rdParty/Boost/src/boost/thread/detail/lockable_wrapper.hpp45
-rw-r--r--3rdParty/Boost/src/boost/thread/detail/make_tuple_indices.hpp224
-rw-r--r--3rdParty/Boost/src/boost/thread/detail/memory.hpp130
-rw-r--r--3rdParty/Boost/src/boost/thread/detail/move.hpp106
-rw-r--r--3rdParty/Boost/src/boost/thread/detail/nullary_function.hpp213
-rw-r--r--3rdParty/Boost/src/boost/thread/detail/thread.hpp304
-rw-r--r--3rdParty/Boost/src/boost/thread/detail/thread_group.hpp64
-rw-r--r--3rdParty/Boost/src/boost/thread/detail/thread_interruption.hpp5
-rw-r--r--3rdParty/Boost/src/boost/thread/detail/variadic_footer.hpp10
-rw-r--r--3rdParty/Boost/src/boost/thread/detail/variadic_header.hpp19
-rw-r--r--3rdParty/Boost/src/boost/thread/exceptional_ptr.hpp44
-rw-r--r--3rdParty/Boost/src/boost/thread/exceptions.hpp10
-rw-r--r--3rdParty/Boost/src/boost/thread/future.hpp4129
-rw-r--r--3rdParty/Boost/src/boost/thread/future_error_code.hpp61
-rw-r--r--3rdParty/Boost/src/boost/thread/is_locked_by_this_thread.hpp39
-rw-r--r--3rdParty/Boost/src/boost/thread/lock_algorithms.hpp468
-rw-r--r--3rdParty/Boost/src/boost/thread/lock_guard.hpp88
-rw-r--r--3rdParty/Boost/src/boost/thread/lock_options.hpp31
-rw-r--r--3rdParty/Boost/src/boost/thread/lock_types.hpp1230
-rw-r--r--3rdParty/Boost/src/boost/thread/lockable_traits.hpp207
-rw-r--r--3rdParty/Boost/src/boost/thread/locks.hpp1821
-rw-r--r--3rdParty/Boost/src/boost/thread/mutex.hpp34
-rw-r--r--3rdParty/Boost/src/boost/thread/once.hpp11
-rw-r--r--3rdParty/Boost/src/boost/thread/pthread/condition_variable.hpp114
-rw-r--r--3rdParty/Boost/src/boost/thread/pthread/condition_variable_fwd.hpp95
-rw-r--r--3rdParty/Boost/src/boost/thread/pthread/mutex.hpp142
-rw-r--r--3rdParty/Boost/src/boost/thread/pthread/once.hpp505
-rw-r--r--3rdParty/Boost/src/boost/thread/pthread/once_atomic.hpp313
-rw-r--r--3rdParty/Boost/src/boost/thread/pthread/recursive_mutex.hpp29
-rw-r--r--3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp287
-rw-r--r--3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp125
-rw-r--r--3rdParty/Boost/src/boost/thread/pthread/timespec.hpp108
-rw-r--r--3rdParty/Boost/src/boost/thread/recursive_mutex.hpp45
-rw-r--r--3rdParty/Boost/src/boost/thread/shared_mutex.hpp23
-rw-r--r--3rdParty/Boost/src/boost/thread/thread.hpp14
-rw-r--r--3rdParty/Boost/src/boost/thread/thread_only.hpp29
-rw-r--r--3rdParty/Boost/src/boost/thread/v2/thread.hpp96
-rw-r--r--3rdParty/Boost/src/boost/thread/win32/basic_recursive_mutex.hpp4
-rw-r--r--3rdParty/Boost/src/boost/thread/win32/basic_timed_mutex.hpp17
-rw-r--r--3rdParty/Boost/src/boost/thread/win32/condition_variable.hpp54
-rw-r--r--3rdParty/Boost/src/boost/thread/win32/mutex.hpp9
-rw-r--r--3rdParty/Boost/src/boost/thread/win32/once.hpp956
-rw-r--r--3rdParty/Boost/src/boost/thread/win32/recursive_mutex.hpp9
-rw-r--r--3rdParty/Boost/src/boost/thread/win32/shared_mutex.hpp37
-rw-r--r--3rdParty/Boost/src/boost/thread/win32/thread_data.hpp79
-rw-r--r--3rdParty/Boost/src/boost/thread/win32/thread_heap_alloc.hpp101
-rw-r--r--3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp95
-rw-r--r--3rdParty/Boost/src/boost/thread/xtime.hpp3
62 files changed, 12667 insertions, 3130 deletions
diff --git a/3rdParty/Boost/src/boost/thread/barrier.hpp b/3rdParty/Boost/src/boost/thread/barrier.hpp
index 4fd8988..acf0a01 100644
--- a/3rdParty/Boost/src/boost/thread/barrier.hpp
+++ b/3rdParty/Boost/src/boost/thread/barrier.hpp
@@ -1,6 +1,7 @@
// 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)
@@ -9,55 +10,236 @@
#define BOOST_BARRIER_JDM030602_HPP
#include <boost/thread/detail/config.hpp>
-#include <boost/throw_exception.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)
+
+ 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)
+ {}
- class barrier
+ BOOST_THREAD_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_)
+ {
+ }
+
+ unsigned int operator()()
+ {
+ fct_();
+ return size_;
+ }
+ };
+ struct void_fct_ptr_barrier_reseter
{
- public:
- barrier(unsigned int count)
- : m_threshold(count), m_count(count), m_generation(0)
- {
- if (count == 0)
- boost::throw_exception(thread_exception(system::errc::invalid_argument, "barrier constructor: count cannot be zero."));
- }
-
- bool wait()
- {
- boost::mutex::scoped_lock lock(m_mutex);
- unsigned int gen = m_generation;
-
- if (--m_count == 0)
- {
- m_generation++;
- m_count = m_threshold;
- m_cond.notify_all();
- return true;
- }
-
- while (gen == m_generation)
- m_cond.wait(lock);
- return false;
- }
-
- private:
- mutex m_mutex;
- condition_variable m_cond;
- unsigned int m_threshold;
- unsigned int m_count;
- unsigned int m_generation;
+ 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)
+
+ 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_;
+ }
};
+ }
+ 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
+} // namespace boost
#include <boost/config/abi_suffix.hpp>
diff --git a/3rdParty/Boost/src/boost/thread/csbl/memory/allocator_arg.hpp b/3rdParty/Boost/src/boost/thread/csbl/memory/allocator_arg.hpp
new file mode 100644
index 0000000..354cdae
--- /dev/null
+++ b/3rdParty/Boost/src/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/3rdParty/Boost/src/boost/thread/csbl/memory/allocator_traits.hpp b/3rdParty/Boost/src/boost/thread/csbl/memory/allocator_traits.hpp
new file mode 100644
index 0000000..3737cd8
--- /dev/null
+++ b/3rdParty/Boost/src/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/3rdParty/Boost/src/boost/thread/csbl/memory/config.hpp b/3rdParty/Boost/src/boost/thread/csbl/memory/config.hpp
new file mode 100644
index 0000000..7b0596a
--- /dev/null
+++ b/3rdParty/Boost/src/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/3rdParty/Boost/src/boost/thread/csbl/memory/pointer_traits.hpp b/3rdParty/Boost/src/boost/thread/csbl/memory/pointer_traits.hpp
new file mode 100644
index 0000000..320f8e9
--- /dev/null
+++ b/3rdParty/Boost/src/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/3rdParty/Boost/src/boost/thread/csbl/memory/scoped_allocator.hpp b/3rdParty/Boost/src/boost/thread/csbl/memory/scoped_allocator.hpp
new file mode 100644
index 0000000..a92f3d8
--- /dev/null
+++ b/3rdParty/Boost/src/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/3rdParty/Boost/src/boost/thread/csbl/tuple.hpp b/3rdParty/Boost/src/boost/thread/csbl/tuple.hpp
new file mode 100644
index 0000000..146d1c1
--- /dev/null
+++ b/3rdParty/Boost/src/boost/thread/csbl/tuple.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_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;
+#else
+ // 20.4.2, class template tuple:
+ using ::std::tuple;
+ using ::std::get;
+ // 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/3rdParty/Boost/src/boost/thread/csbl/vector.hpp b/3rdParty/Boost/src/boost/thread/csbl/vector.hpp
new file mode 100644
index 0000000..d39c87d
--- /dev/null
+++ b/3rdParty/Boost/src/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_HDR_VECTOR || defined BOOST_NO_CXX11_RVALUE_REFERENCES
+#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/3rdParty/Boost/src/boost/thread/cv_status.hpp b/3rdParty/Boost/src/boost/thread/cv_status.hpp
index 99b3c0c..e52de4a 100644
--- a/3rdParty/Boost/src/boost/thread/cv_status.hpp
+++ b/3rdParty/Boost/src/boost/thread/cv_status.hpp
@@ -9,7 +9,7 @@
#ifndef BOOST_THREAD_CV_STATUS_HPP
#define BOOST_THREAD_CV_STATUS_HPP
-#include <boost/detail/scoped_enum_emulation.hpp>
+#include <boost/core/scoped_enum.hpp>
namespace boost
{
diff --git a/3rdParty/Boost/src/boost/thread/detail/config.hpp b/3rdParty/Boost/src/boost/thread/detail/config.hpp
index 87bad34..5ffe5e4 100644
--- a/3rdParty/Boost/src/boost/thread/detail/config.hpp
+++ b/3rdParty/Boost/src/boost/thread/detail/config.hpp
@@ -1,6 +1,6 @@
// Copyright (C) 2001-2003
// William E. Kempf
-// Copyright (C) 2011-2012 Vicente J. Botet Escriba
+// 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)
@@ -8,111 +8,192 @@
#ifndef BOOST_THREAD_CONFIG_WEK01032003_HPP
#define BOOST_THREAD_CONFIG_WEK01032003_HPP
-// Force SIG_ATOMIC_MAX to be defined
-//#ifndef __STDC_LIMIT_MACROS
-//#define __STDC_LIMIT_MACROS
-//#endif
-
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
+#include <boost/thread/detail/platform.hpp>
+
+//#define BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS
+// ATTRIBUTE_MAY_ALIAS
-#ifdef BOOST_NO_NOEXCEPT
-# define BOOST_THREAD_NOEXCEPT_OR_THROW throw()
+#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_NOEXCEPT_OR_THROW noexcept
+ #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
+#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
+#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
+#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
+#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_THREAD_DONT_PROVIDE_BASIC_THREAD_ID && ! defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
+
+#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
-// Default version is 2
+/// 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
-#error "BOOST_THREAD_VERSION must be 2 or 3"
+#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
+#if ! defined BOOST_THREAD_DONT_USE_CHRONO \
+ && ! defined BOOST_THREAD_USES_CHRONO
#define BOOST_THREAD_USES_CHRONO
#endif
-// Don't provided by default in version 1.
-#if defined BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
-#define BOOST_THREAD_EXPLICIT_LOCK_CONVERSION explicit
-#else
-#define BOOST_THREAD_EXPLICIT_LOCK_CONVERSION
+#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
-#if ! defined BOOST_THREAD_DONT_PROVIDE_PROMISE_LAZY && ! defined BOOST_THREAD_PROMISE_LAZY
-#define BOOST_THREAD_PROMISE_LAZY
+
+// PROVIDE_PROMISE_LAZY
+#if ! defined BOOST_THREAD_DONT_PROVIDE_PROMISE_LAZY \
+ && ! defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
+#define BOOST_THREAD_PROVIDES_PROMISE_LAZY
#endif
-#if ! defined BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0
-#define BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
+
+// 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
+#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_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
-#if ! defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 \
- && ! defined BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_
-#define BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0
-#endif
+
+// USE_MOVE
#if ! defined BOOST_THREAD_DONT_USE_MOVE \
&& ! defined BOOST_THREAD_USES_MOVE
#define BOOST_THREAD_USES_MOVE
@@ -120,17 +201,157 @@
#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_THREAD_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
-// BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 defined by default up to Boost 1.52
+// 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_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0 \
-&& ! defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
-#define BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
+#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 BOOST_WORKAROUND(__BORLANDC__, < 0x600)
@@ -142,6 +363,13 @@
#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
@@ -151,7 +379,9 @@
// 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
-# define BOOST_THREAD_USE_DLL
+# if !defined(BOOST_THREAD_USE_DLL)
+# define BOOST_THREAD_USE_DLL
+# endif
#endif
#if defined(BOOST_THREAD_BUILD_DLL) //Build dll
@@ -160,8 +390,9 @@
#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)
- //For compilers supporting auto-tss cleanup
+# 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
diff --git a/3rdParty/Boost/src/boost/thread/detail/delete.hpp b/3rdParty/Boost/src/boost/thread/detail/delete.hpp
index 30e7c93..4caa340 100644
--- a/3rdParty/Boost/src/boost/thread/detail/delete.hpp
+++ b/3rdParty/Boost/src/boost/thread/detail/delete.hpp
@@ -15,6 +15,7 @@
* BOOST_THREAD_DELETE_COPY_ASSIGN deletes the copy assignment when the compiler supports it or
* makes it private.
*/
+
#ifndef BOOST_NO_CXX11_DELETED_FUNCTIONS
#define BOOST_THREAD_DELETE_COPY_CTOR(CLASS) \
CLASS(CLASS const&) = delete; \
@@ -23,6 +24,17 @@
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&); \
@@ -32,6 +44,7 @@
private: \
CLASS& operator=(CLASS&); \
public:
+#endif
#endif // BOOST_NO_CXX11_DELETED_FUNCTIONS
/**
diff --git a/3rdParty/Boost/src/boost/thread/detail/invoke.hpp b/3rdParty/Boost/src/boost/thread/detail/invoke.hpp
new file mode 100644
index 0000000..c81f50f
--- /dev/null
+++ b/3rdParty/Boost/src/boost/thread/detail/invoke.hpp
@@ -0,0 +1,1606 @@
+// 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_THREAD_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
+
+//#error
+ 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/3rdParty/Boost/src/boost/thread/detail/invoker.hpp b/3rdParty/Boost/src/boost/thread/detail/invoker.hpp
new file mode 100644
index 0000000..aeac530
--- /dev/null
+++ b/3rdParty/Boost/src/boost/thread/detail/invoker.hpp
@@ -0,0 +1,738 @@
+// 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_ASYNC_FUNCT_HPP
+#define BOOST_THREAD_DETAIL_ASYNC_FUNCT_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_MOVABLE_ONLY( 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_))
+ {}
+
+ 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 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_MOVABLE_ONLY( 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 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
+
+#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_MOVABLE_ONLY(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_FWD_REF(invoker) x) \
+ : fp_(boost::move(x.fp_)) \
+ BOOST_PP_REPEAT(n, BOOST_THREAD_MOVE_RHS_PARAM, ~) \
+ {} \
+ \
+ result_type operator()() { \
+ return 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_MOVABLE_ONLY(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_FWD_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_MOVABLE_ONLY(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_FWD_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 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_MOVABLE_ONLY(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_FWD_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 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_MOVABLE_ONLY(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_FWD_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 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_MOVABLE_ONLY(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_FWD_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 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_MOVABLE_ONLY(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_FWD_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 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_MOVABLE_ONLY(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_FWD_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 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_MOVABLE_ONLY(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_FWD_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 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_MOVABLE_ONLY(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_FWD_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 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_MOVABLE_ONLY(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_FWD_REF(invoker) f)
+ : fp_(boost::move(BOOST_THREAD_RV(f).fp))
+ , v0_(boost::move(BOOST_THREAD_RV(f).v0_))
+ {}
+
+ result_type operator()()
+ {
+ return 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_FWD_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_FWD_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/3rdParty/Boost/src/boost/thread/detail/is_convertible.hpp b/3rdParty/Boost/src/boost/thread/detail/is_convertible.hpp
new file mode 100644
index 0000000..b77620c
--- /dev/null
+++ b/3rdParty/Boost/src/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/3rdParty/Boost/src/boost/thread/detail/lockable_wrapper.hpp b/3rdParty/Boost/src/boost/thread/detail/lockable_wrapper.hpp
new file mode 100644
index 0000000..8dc5a6c
--- /dev/null
+++ b/3rdParty/Boost/src/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/3rdParty/Boost/src/boost/thread/detail/make_tuple_indices.hpp b/3rdParty/Boost/src/boost/thread/detail/make_tuple_indices.hpp
new file mode 100644
index 0000000..73d54f1
--- /dev/null
+++ b/3rdParty/Boost/src/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/3rdParty/Boost/src/boost/thread/detail/memory.hpp b/3rdParty/Boost/src/boost/thread/detail/memory.hpp
index 3c1692d..51ce84f 100644
--- a/3rdParty/Boost/src/boost/thread/detail/memory.hpp
+++ b/3rdParty/Boost/src/boost/thread/detail/memory.hpp
@@ -1,8 +1,9 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright 2011-2012 Vicente J. Botet Escriba
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+// 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.
//
@@ -12,14 +13,11 @@
#define BOOST_THREAD_DETAIL_MEMORY_HPP
#include <boost/config.hpp>
-#include <boost/container/allocator_traits.hpp>
-#include <boost/container/scoped_allocator.hpp>
-#include <boost/type_traits/remove_cv.hpp>
-#include <boost/type_traits/is_convertible.hpp>
-#include <boost/type_traits/is_scalar.hpp>
-#include <boost/type_traits/is_pointer.hpp>
-#include <boost/type_traits/is_same.hpp>
-#include <boost/static_assert.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
{
@@ -28,7 +26,7 @@ namespace boost
template <class _Alloc>
class allocator_destructor
{
- typedef container::allocator_traits<_Alloc> alloc_traits;
+ typedef csbl::allocator_traits<_Alloc> alloc_traits;
public:
typedef typename alloc_traits::pointer pointer;
typedef typename alloc_traits::size_type size_type;
@@ -46,111 +44,5 @@ namespace boost
}
};
} //namespace thread_detail
-
- typedef container::allocator_arg_t allocator_arg_t;
- BOOST_CONSTEXPR_OR_CONST allocator_arg_t allocator_arg = {};
-
- template <class T, class Alloc>
- struct uses_allocator: public container::uses_allocator<T, Alloc>
- {
- };
-
- template <class Ptr>
- struct pointer_traits
- {
- typedef Ptr pointer;
-// typedef <details> element_type;
-// typedef <details> difference_type;
-
-// template <class U> using rebind = <details>;
-//
-// static pointer pointer_to(<details>);
- };
-
- template <class T>
- struct pointer_traits<T*>
- {
- typedef T* pointer;
- typedef T element_type;
- typedef ptrdiff_t difference_type;
-
-// template <class U> using rebind = U*;
-//
-// static pointer pointer_to(<details>) noexcept;
- };
-
-
- namespace thread_detail {
- template <class _Ptr1, class _Ptr2,
- bool = is_same<typename remove_cv<typename pointer_traits<_Ptr1>::element_type>::type,
- typename remove_cv<typename pointer_traits<_Ptr2>::element_type>::type
- >::value
- >
- struct same_or_less_cv_qualified_imp
- : is_convertible<_Ptr1, _Ptr2> {};
-
- template <class _Ptr1, class _Ptr2>
- struct same_or_less_cv_qualified_imp<_Ptr1, _Ptr2, false>
- : false_type {};
-
- template <class _Ptr1, class _Ptr2, bool = is_scalar<_Ptr1>::value &&
- !is_pointer<_Ptr1>::value>
- struct same_or_less_cv_qualified
- : same_or_less_cv_qualified_imp<_Ptr1, _Ptr2> {};
-
- template <class _Ptr1, class _Ptr2>
- struct same_or_less_cv_qualified<_Ptr1, _Ptr2, true>
- : false_type {};
-
- }
- template <class T>
- struct BOOST_SYMBOL_VISIBLE default_delete
- {
- #ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
- BOOST_SYMBOL_VISIBLE
- BOOST_CONSTEXPR default_delete() = default;
- #else
- BOOST_SYMBOL_VISIBLE
- BOOST_CONSTEXPR default_delete() BOOST_NOEXCEPT {}
- #endif
- template <class U>
- BOOST_SYMBOL_VISIBLE
- default_delete(const default_delete<U>&,
- typename enable_if<is_convertible<U*, T*> >::type* = 0) BOOST_NOEXCEPT {}
- BOOST_SYMBOL_VISIBLE
- void operator() (T* ptr) const BOOST_NOEXCEPT
- {
- BOOST_STATIC_ASSERT_MSG(sizeof(T) > 0, "default_delete can not delete incomplete type");
- delete ptr;
- }
- };
-
- template <class T>
- struct BOOST_SYMBOL_VISIBLE default_delete<T[]>
- {
- public:
- #ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
- BOOST_SYMBOL_VISIBLE
- BOOST_CONSTEXPR default_delete() = default;
- #else
- BOOST_SYMBOL_VISIBLE
- BOOST_CONSTEXPR default_delete() BOOST_NOEXCEPT {}
- #endif
- template <class U>
- BOOST_SYMBOL_VISIBLE
- default_delete(const default_delete<U[]>&,
- typename enable_if<thread_detail::same_or_less_cv_qualified<U*, T*> >::type* = 0) BOOST_NOEXCEPT {}
- template <class U>
- BOOST_SYMBOL_VISIBLE
- void operator() (U* ptr,
- typename enable_if<thread_detail::same_or_less_cv_qualified<U*, T*> >::type* = 0) const BOOST_NOEXCEPT
- {
- BOOST_STATIC_ASSERT_MSG(sizeof(T) > 0, "default_delete can not delete incomplete type");
- delete [] ptr;
- }
- };
-
-} // namespace boost
-
-
+}
#endif // BOOST_THREAD_DETAIL_MEMORY_HPP
diff --git a/3rdParty/Boost/src/boost/thread/detail/move.hpp b/3rdParty/Boost/src/boost/thread/detail/move.hpp
index f2665e6..c3339ef 100644
--- a/3rdParty/Boost/src/boost/thread/detail/move.hpp
+++ b/3rdParty/Boost/src/boost/thread/detail/move.hpp
@@ -9,24 +9,34 @@
#include <boost/thread/detail/config.hpp>
#ifndef BOOST_NO_SFINAE
-#include <boost/utility/enable_if.hpp>
+#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/move.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 has_move_emulation_enabled_aux_dummy_specialization;
+ struct enable_move_utility_emulation_dummy_specialization;
template<typename T>
struct thread_move_t
{
@@ -49,6 +59,7 @@ namespace boost
};
}
+#if !defined BOOST_THREAD_USES_MOVE
#ifndef BOOST_NO_SFINAE
template<typename T>
@@ -63,11 +74,14 @@ namespace boost
{
return t;
}
+
+#endif //#if !defined BOOST_THREAD_USES_MOVE
}
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
#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
@@ -77,16 +91,17 @@ namespace boost
#define BOOST_THREAD_DCL_MOVABLE_BEG(T) \
namespace detail { \
template <typename T> \
- struct has_move_emulation_enabled_aux_dummy_specialization<
+ struct enable_move_utility_emulation_dummy_specialization<
#define BOOST_THREAD_DCL_MOVABLE_END > \
- : integral_constant<bool, true> \
+ : integral_constant<bool, false> \
{}; \
}
#elif ! defined BOOST_NO_CXX11_RVALUE_REFERENCES && defined BOOST_MSVC
#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
@@ -96,10 +111,10 @@ namespace boost
#define BOOST_THREAD_DCL_MOVABLE_BEG(T) \
namespace detail { \
template <typename T> \
- struct has_move_emulation_enabled_aux_dummy_specialization<
+ struct enable_move_utility_emulation_dummy_specialization<
#define BOOST_THREAD_DCL_MOVABLE_END > \
- : integral_constant<bool, true> \
+ : integral_constant<bool, false> \
{}; \
}
@@ -107,6 +122,7 @@ namespace boost
#if defined BOOST_THREAD_USES_MOVE
#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
@@ -115,10 +131,10 @@ namespace boost
#define BOOST_THREAD_DCL_MOVABLE_BEG(T) \
namespace detail { \
template <typename T> \
- struct has_move_emulation_enabled_aux_dummy_specialization<
+ struct enable_move_utility_emulation_dummy_specialization<
#define BOOST_THREAD_DCL_MOVABLE_END > \
- : integral_constant<bool, true> \
+ : integral_constant<bool, false> \
{}; \
}
@@ -132,17 +148,19 @@ namespace boost
#define BOOST_THREAD_DCL_MOVABLE(TYPE) \
template <> \
-struct has_move_emulation_enabled_aux< TYPE > \
- : BOOST_MOVE_BOOST_NS::integral_constant<bool, true> \
-{};
+struct enable_move_utility_emulation< TYPE > \
+{ \
+ static const bool value = false; \
+};
#define BOOST_THREAD_DCL_MOVABLE_BEG(T) \
template <typename T> \
-struct has_move_emulation_enabled_aux<
+struct enable_move_utility_emulation<
#define BOOST_THREAD_DCL_MOVABLE_END > \
- : BOOST_MOVE_BOOST_NS::integral_constant<bool, true> \
-{};
+{ \
+ static const bool value = false; \
+};
#endif
@@ -227,19 +245,69 @@ namespace detail
-#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
namespace boost
-{ namespace thread_detail
+{
+ namespace thread_detail
+ {
+#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>
diff --git a/3rdParty/Boost/src/boost/thread/detail/nullary_function.hpp b/3rdParty/Boost/src/boost/thread/detail/nullary_function.hpp
new file mode 100644
index 0000000..26d1390
--- /dev/null
+++ b/3rdParty/Boost/src/boost/thread/detail/nullary_function.hpp
@@ -0,0 +1,213 @@
+// 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/smart_ptr/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()
+ {
+ }
+ };
+ 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_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 :
+ impl(BOOST_THREAD_RV(other).impl)
+ {
+ BOOST_THREAD_RV(other).impl.reset();
+ }
+ ~nullary_function()
+ {
+ }
+
+ nullary_function& operator=(nullary_function const& other) BOOST_NOEXCEPT
+ {
+ impl=other.impl;
+ return *this;
+ }
+ nullary_function& operator=(BOOST_THREAD_RV_REF(nullary_function) other) BOOST_NOEXCEPT
+ {
+ impl=BOOST_THREAD_RV(other).impl;
+ BOOST_THREAD_RV(other).impl.reset();
+ return *this;
+ }
+
+
+ void operator()()
+ { impl->call();}
+
+ };
+
+ template <typename R>
+ class nullary_function<R()>
+ {
+ struct impl_base
+ {
+ virtual R call()=0;
+ virtual ~impl_base()
+ {
+ }
+ };
+ 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_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 :
+ impl(BOOST_THREAD_RV(other).impl)
+ {
+ BOOST_THREAD_RV(other).impl.reset();
+ }
+ nullary_function()
+ : impl()
+ {
+ }
+ ~nullary_function()
+ {
+ }
+
+ nullary_function& operator=(nullary_function const& other) BOOST_NOEXCEPT
+ {
+ impl=other.impl;
+ return *this;
+ }
+ nullary_function& operator=(BOOST_THREAD_RV_REF(nullary_function) other) BOOST_NOEXCEPT
+ {
+ impl=BOOST_THREAD_RV(other).impl;
+ BOOST_THREAD_RV(other).impl.reset();
+ return *this;
+ }
+
+ R operator()()
+ { return impl->call();}
+
+ };
+ }
+}
+
+#endif // header
diff --git a/3rdParty/Boost/src/boost/thread/detail/thread.hpp b/3rdParty/Boost/src/boost/thread/detail/thread.hpp
index 2590f45..520ca26 100644
--- a/3rdParty/Boost/src/boost/thread/detail/thread.hpp
+++ b/3rdParty/Boost/src/boost/thread/detail/thread.hpp
@@ -3,29 +3,33 @@
// Distributed under the 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 20011-12 Vicente J. Botet Escriba
+// (C) Copyright 2007-2010 Anthony Williams
+// (C) Copyright 2011-2012 Vicente J. Botet Escriba
#include <boost/thread/detail/config.hpp>
+
#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/ref.hpp>
+#include <boost/core/ref.hpp>
#include <boost/cstdint.hpp>
#include <boost/bind.hpp>
#include <stdlib.h>
#include <memory>
-//#include <vector>
-//#include <utility>
-#include <boost/utility/enable_if.hpp>
+#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>
@@ -36,6 +40,9 @@
#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
@@ -48,6 +55,36 @@ 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...>)
+ {
+
+ 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
@@ -115,6 +152,7 @@ namespace boost
f();
}
};
+#endif
}
class BOOST_THREAD_DECL thread
@@ -125,24 +163,55 @@ namespace boost
BOOST_THREAD_MOVABLE_ONLY(thread)
private:
+ struct dummy;
+
void release_handle();
detail::thread_data_ptr thread_info;
- void start_thread();
- void start_thread(const attributes& attr);
+ private:
+ bool start_thread_noexcept();
+ bool start_thread_noexcept(const attributes& attr);
+ //public:
+ 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(*)()> >(
@@ -150,7 +219,12 @@ namespace boost
}
#else
template<typename F>
- static inline detail::thread_data_ptr make_thread_info(F 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));
}
@@ -161,7 +235,6 @@ namespace boost
}
#endif
- struct dummy;
public:
#if 0 // This should not be needed anymore. Use instead BOOST_THREAD_MAKE_RV_REF.
#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
@@ -171,6 +244,7 @@ namespace boost
thread() BOOST_NOEXCEPT;
~thread()
{
+
#if defined BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE
if (joinable()) {
std::terminate();
@@ -184,7 +258,7 @@ namespace boost
class F
>
explicit thread(BOOST_THREAD_RV_REF(F) f
- , typename disable_if<is_same<typename decay<F>::type, thread>, dummy* >::type=0
+ //, 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))))
{
@@ -193,7 +267,7 @@ namespace boost
template <
class F
>
- thread(attributes& attrs, BOOST_THREAD_RV_REF(F) 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);
@@ -208,7 +282,7 @@ namespace boost
start_thread();
}
template <class F>
- thread(attributes& attrs, F f):
+ thread(attributes const& attrs, F f):
thread_info(make_thread_info(f))
{
start_thread(attrs);
@@ -216,15 +290,19 @@ namespace boost
#else
template <class F>
explicit thread(F f
- // todo Disable also if Or is_same<typename decay<F>::type, thread>
- , typename disable_if<boost::is_convertible<F&,BOOST_THREAD_RV_REF(F) >, dummy* >::type=0):
+ , 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
+ ):
thread_info(make_thread_info(f))
{
start_thread();
}
template <class F>
- thread(attributes& attrs, F f
- , typename disable_if<boost::is_convertible<F&,BOOST_THREAD_RV_REF(F) >, dummy* >::type=0):
+ thread(attributes const& attrs, F f
+ , 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);
@@ -234,19 +312,27 @@ namespace boost
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(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();
}
template <class F>
- thread(attributes& attrs, BOOST_THREAD_RV_REF(F) f):
- thread_info(make_thread_info(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)
+ thread(BOOST_THREAD_RV_REF(thread) x) BOOST_NOEXCEPT
{
thread_info=BOOST_THREAD_RV(x).thread_info;
BOOST_THREAD_RV(x).thread_info.reset();
@@ -272,8 +358,32 @@ namespace boost
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::is_convertible<F&,thread_attributes >, dummy* >::type=0):
+ 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();
@@ -333,31 +443,53 @@ namespace boost
{
start_thread();
}
-
+#endif
void swap(thread& x) BOOST_NOEXCEPT
{
thread_info.swap(x.thread_info);
}
- class BOOST_SYMBOL_VISIBLE id;
+ 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;
- void join();
+ 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;
system_clock::time_point s_now = system_clock::now();
- typename Clock::time_point c_now = Clock::now();
- return try_join_until(s_now + ceil<nanoseconds>(t - c_now));
+ bool joined= false;
+ do {
+ 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)
@@ -368,10 +500,15 @@ namespace boost
}
#endif
#if defined(BOOST_THREAD_PLATFORM_WIN32)
- bool timed_join(const system_time& abs_time);
private:
- bool do_try_join_until(uintmax_t milli);
+ 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)
{
@@ -382,49 +519,53 @@ namespace boost
#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::get_timespec(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;
- seconds s = duration_cast<seconds>(d);
- ts.tv_sec = static_cast<long>(s.count());
- ts.tv_nsec = static_cast<long>((d - s).count());
+ timespec ts = boost::detail::to_timespec(d);
return do_try_join_until(ts);
}
#endif
- private:
- bool do_try_join_until(struct timespec const &timeout);
- public:
#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_DEPRECATED_FEATURES_SINCE_V3_0_0
+#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();
@@ -434,10 +575,13 @@ namespace boost
{
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
@@ -456,16 +600,24 @@ namespace boost
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
@@ -501,11 +653,7 @@ namespace boost
public:
id() BOOST_NOEXCEPT:
#if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
-#if defined(BOOST_THREAD_PLATFORM_WIN32)
- thread_data(0)
-#else
thread_data(0)
-#endif
#else
thread_data()
#endif
@@ -583,6 +731,61 @@ namespace boost
#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
@@ -593,7 +796,7 @@ namespace boost
}
#endif
-#if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
+#if defined BOOST_THREAD_PROVIDES_THREAD_EQ
inline bool thread::operator==(const thread& other) const
{
return get_id()==other.get_id();
@@ -631,6 +834,19 @@ namespace boost
};
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
diff --git a/3rdParty/Boost/src/boost/thread/detail/thread_group.hpp b/3rdParty/Boost/src/boost/thread/detail/thread_group.hpp
index f1ccdf8..69ce991 100644
--- a/3rdParty/Boost/src/boost/thread/detail/thread_group.hpp
+++ b/3rdParty/Boost/src/boost/thread/detail/thread_group.hpp
@@ -8,6 +8,7 @@
#include <list>
#include <boost/thread/shared_mutex.hpp>
#include <boost/thread/mutex.hpp>
+#include <boost/thread/lock_guard.hpp>
#include <boost/config/abi_prefix.hpp>
@@ -22,7 +23,7 @@ namespace boost
{
private:
thread_group(thread_group const&);
- thread_group& operator=(thread_group const&);
+ thread_group& operator=(thread_group const&);
public:
thread_group() {}
~thread_group()
@@ -35,6 +36,41 @@ namespace boost
}
}
+ 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)
{
@@ -43,16 +79,20 @@ namespace boost
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);
@@ -62,23 +102,28 @@ namespace boost
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)
@@ -86,13 +131,14 @@ namespace boost
(*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;
diff --git a/3rdParty/Boost/src/boost/thread/detail/thread_interruption.hpp b/3rdParty/Boost/src/boost/thread/detail/thread_interruption.hpp
index f1a165c..5d7d10f 100644
--- a/3rdParty/Boost/src/boost/thread/detail/thread_interruption.hpp
+++ b/3rdParty/Boost/src/boost/thread/detail/thread_interruption.hpp
@@ -9,6 +9,8 @@
#include <boost/thread/detail/config.hpp>
#include <boost/thread/detail/delete.hpp>
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+
namespace boost
{
namespace this_thread
@@ -33,4 +35,5 @@ namespace boost
}
}
-#endif
+#endif // BOOST_THREAD_PROVIDES_INTERRUPTIONS
+#endif // header
diff --git a/3rdParty/Boost/src/boost/thread/detail/variadic_footer.hpp b/3rdParty/Boost/src/boost/thread/detail/variadic_footer.hpp
new file mode 100644
index 0000000..9ae25a8
--- /dev/null
+++ b/3rdParty/Boost/src/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/3rdParty/Boost/src/boost/thread/detail/variadic_header.hpp b/3rdParty/Boost/src/boost/thread/detail/variadic_header.hpp
new file mode 100644
index 0000000..8015ae3
--- /dev/null
+++ b/3rdParty/Boost/src/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/3rdParty/Boost/src/boost/thread/exceptional_ptr.hpp b/3rdParty/Boost/src/boost/thread/exceptional_ptr.hpp
new file mode 100644
index 0000000..4954792
--- /dev/null
+++ b/3rdParty/Boost/src/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/3rdParty/Boost/src/boost/thread/exceptions.hpp b/3rdParty/Boost/src/boost/thread/exceptions.hpp
index 08c28d3..d97465b 100644
--- a/3rdParty/Boost/src/boost/thread/exceptions.hpp
+++ b/3rdParty/Boost/src/boost/thread/exceptions.hpp
@@ -28,8 +28,10 @@
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
@@ -122,7 +124,7 @@ namespace boost
typedef thread_exception base_type;
public:
thread_resource_error()
- : base_type(system::errc::resource_unavailable_try_again, "boost::thread_resource_error")
+ : base_type(static_cast<int>(system::errc::resource_unavailable_try_again), "boost::thread_resource_error")
{}
thread_resource_error( int ev )
@@ -150,7 +152,7 @@ namespace boost
typedef thread_exception base_type;
public:
unsupported_thread_option()
- : base_type(system::errc::invalid_argument, "boost::unsupported_thread_option")
+ : base_type(static_cast<int>(system::errc::invalid_argument), "boost::unsupported_thread_option")
{}
unsupported_thread_option( int ev )
@@ -174,7 +176,7 @@ namespace boost
typedef thread_exception base_type;
public:
invalid_thread_argument()
- : base_type(system::errc::invalid_argument, "boost::invalid_thread_argument")
+ : base_type(static_cast<int>(system::errc::invalid_argument), "boost::invalid_thread_argument")
{}
invalid_thread_argument( int ev )
@@ -198,7 +200,7 @@ namespace boost
typedef thread_exception base_type;
public:
thread_permission_error()
- : base_type(system::errc::permission_denied, "boost::thread_permission_error")
+ : base_type(static_cast<int>(system::errc::permission_denied), "boost::thread_permission_error")
{}
thread_permission_error( int ev )
diff --git a/3rdParty/Boost/src/boost/thread/future.hpp b/3rdParty/Boost/src/boost/thread/future.hpp
index 6bf5cf6..5f55707 100644
--- a/3rdParty/Boost/src/boost/thread/future.hpp
+++ b/3rdParty/Boost/src/boost/thread/future.hpp
@@ -1,5 +1,5 @@
// (C) Copyright 2008-10 Anthony Williams
-// (C) Copyright 2011-2012 Vicente J. Botet Escriba
+// (C) Copyright 2011-2014 Vicente J. Botet Escriba
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -15,42 +15,58 @@
#ifndef BOOST_NO_EXCEPTIONS
-#include <boost/detail/scoped_enum_emulation.hpp>
+#include <boost/core/scoped_enum.hpp>
#include <stdexcept>
+#include <boost/thread/exceptional_ptr.hpp>
#include <boost/thread/detail/move.hpp>
+#include <boost/thread/detail/invoker.hpp>
#include <boost/thread/thread_time.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/lock_algorithms.hpp>
+#include <boost/thread/lock_types.hpp>
#include <boost/exception_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/type_traits/is_fundamental.hpp>
-#include <boost/type_traits/is_convertible.hpp>
-#include <boost/type_traits/remove_reference.hpp>
-#include <boost/type_traits/remove_cv.hpp>
-#include <boost/mpl/if.hpp>
+#include <boost/thread/detail/is_convertible.hpp>
+#include <boost/type_traits/decay.hpp>
+#include <boost/type_traits/is_void.hpp>
+#include <boost/type_traits/conditional.hpp>
#include <boost/config.hpp>
#include <boost/throw_exception.hpp>
#include <algorithm>
#include <boost/function.hpp>
#include <boost/bind.hpp>
-#include <boost/ref.hpp>
+#include <boost/core/ref.hpp>
#include <boost/scoped_array.hpp>
-#include <boost/utility/enable_if.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <boost/core/enable_if.hpp>
+
#include <list>
#include <boost/next_prior.hpp>
#include <vector>
-#include <boost/system/error_code.hpp>
+
+#include <boost/thread/future_error_code.hpp>
#ifdef BOOST_THREAD_USES_CHRONO
#include <boost/chrono/system_clocks.hpp>
#endif
#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
#include <boost/utility/result_of.hpp>
-#include <boost/thread/thread.hpp>
+#include <boost/thread/thread_only.hpp>
+
+#if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
+#include <boost/thread/csbl/tuple.hpp>
+#include <boost/thread/csbl/vector.hpp>
+#endif
#if defined BOOST_THREAD_PROVIDES_FUTURE
#define BOOST_THREAD_FUTURE future
@@ -58,36 +74,18 @@
#define BOOST_THREAD_FUTURE unique_future
#endif
-
namespace boost
{
- //enum class future_errc
- BOOST_SCOPED_ENUM_DECLARE_BEGIN(future_errc)
- {
- broken_promise,
- 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<future_errc> : public true_type {};
-
- #ifdef BOOST_NO_CXX11_SCOPED_ENUMS
- template <>
- struct BOOST_SYMBOL_VISIBLE is_error_code_enum<future_errc::enum_type> : public true_type { };
- #endif
- }
-
//enum class launch
BOOST_SCOPED_ENUM_DECLARE_BEGIN(launch)
{
+ none = 0,
async = 1,
deferred = 2,
+#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
+ executor = 4,
+#endif
any = async | deferred
}
BOOST_SCOPED_ENUM_DECLARE_END(launch)
@@ -101,26 +99,6 @@ namespace boost
}
BOOST_SCOPED_ENUM_DECLARE_END(future_status)
- 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), future_category());
- }
- }
-
class BOOST_SYMBOL_VISIBLE future_error
: public std::logic_error
{
@@ -136,11 +114,6 @@ namespace boost
{
return ec_;
}
- const char* what() const BOOST_THREAD_NOEXCEPT_OR_THROW
- {
- return code().message().c_str();
- }
-
};
class BOOST_SYMBOL_VISIBLE future_uninitialized:
@@ -185,49 +158,111 @@ namespace boost
{}
};
- class BOOST_SYMBOL_VISIBLE task_moved:
- public future_error
- {
- public:
- task_moved():
- future_error(system::make_error_code(future_errc::no_state))
- {}
- };
+ 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))
- {}
- };
+ class promise_moved:
+ public future_error
+ {
+ public:
+ promise_moved():
+ future_error(system::make_error_code(future_errc::no_state))
+ {}
+ };
namespace future_state
{
- enum state { uninitialized, waiting, ready, moved };
+ enum state { uninitialized, waiting, ready, moved, deferred };
}
namespace detail
{
- struct future_object_base
+ struct relocker
+ {
+ boost::unique_lock<boost::mutex>& lock_;
+ bool unlocked_;
+
+ relocker(boost::unique_lock<boost::mutex>& lk):
+ lock_(lk)
+ {
+ lock_.unlock();
+ unlocked_=true;
+ }
+ ~relocker()
+ {
+ if (unlocked_) {
+ lock_.lock();
+ }
+ }
+ void lock() {
+ if (unlocked_) {
+ lock_.lock();
+ unlocked_=false;
+ }
+ }
+ 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;
+ // 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;
+
boost::exception_ptr exception;
bool done;
- bool thread_was_interrupted;
- boost::mutex mutex;
+ bool is_deferred_;
+ launch policy_;
+ bool is_constructed;
+ mutable boost::mutex mutex;
boost::condition_variable waiters;
- typedef std::list<boost::condition_variable_any*> waiter_list;
waiter_list external_waiters;
boost::function<void()> callback;
+ // This declaration should be only included conditionally if interruptions are allowed, but is included to maintain the same layout.
+ bool thread_was_interrupted;
+ // This declaration should be only included conditionally, but is included to maintain the same layout.
+ continuation_ptr_type continuation_ptr;
- future_object_base():
+ // This declaration should be only included conditionally, but is included to maintain the same layout.
+ virtual void launch_continuation(boost::unique_lock<boost::mutex>&)
+ {
+ }
+
+ shared_state_base():
done(false),
- thread_was_interrupted(false)
+ is_deferred_(false),
+ policy_(launch::none),
+ is_constructed(false),
+ thread_was_interrupted(false),
+ continuation_ptr()
{}
- virtual ~future_object_base()
+ virtual ~shared_state_base()
{}
+ 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;
+ }
+#endif
waiter_list::iterator register_external_waiter(boost::condition_variable_any& cv)
{
boost::unique_lock<boost::mutex> lock(mutex);
@@ -241,7 +276,32 @@ namespace boost
external_waiters.erase(it);
}
- void mark_finished_internal()
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
+ void do_continuation(boost::unique_lock<boost::mutex>& lock)
+ {
+ if (continuation_ptr) {
+ continuation_ptr_type this_continuation_ptr = continuation_ptr;
+ continuation_ptr.reset();
+ this_continuation_ptr->launch_continuation(lock);
+ //if (! lock.owns_lock())
+ // lock.lock();
+ }
+ }
+#else
+ void do_continuation(boost::unique_lock<boost::mutex>&)
+ {
+ }
+#endif
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
+ void set_continuation_ptr(continuation_ptr_type continuation, boost::unique_lock<boost::mutex>& lock)
+ {
+ continuation_ptr= continuation;
+ if (done) {
+ do_continuation(lock);
+ }
+ }
+#endif
+ void mark_finished_internal(boost::unique_lock<boost::mutex>& lock)
{
done=true;
waiters.notify_all();
@@ -250,24 +310,13 @@ namespace boost
{
(*it)->notify_all();
}
+ do_continuation(lock);
}
-
- struct relocker
+ void make_ready()
{
- boost::unique_lock<boost::mutex>& lock;
-
- relocker(boost::unique_lock<boost::mutex>& lock_):
- lock(lock_)
- {
- lock.unlock();
- }
- ~relocker()
- {
- lock.lock();
- }
- private:
- relocker& operator=(relocker const&);
- };
+ boost::unique_lock<boost::mutex> lock(mutex);
+ mark_finished_internal(lock);
+ }
void do_callback(boost::unique_lock<boost::mutex>& lock)
{
@@ -279,28 +328,50 @@ namespace boost
}
}
-
- void wait(bool rethrow=true)
+ void wait_internal(boost::unique_lock<boost::mutex> &lk, bool rethrow=true)
{
- boost::unique_lock<boost::mutex> lock(mutex);
- do_callback(lock);
- while(!done)
- {
- waiters.wait(lock);
- }
- if(rethrow && thread_was_interrupted)
+ do_callback(lk);
+ //if (!done) // fixme why this doesn't work?
+ {
+ if (is_deferred_)
{
- throw boost::thread_interrupted();
+ is_deferred_=false;
+ execute(lk);
+ //lk.unlock();
}
- if(rethrow && exception)
+ else
{
- boost::rethrow_exception(exception);
+ while(!done)
+ {
+ waiters.wait(lk);
+ }
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ if(rethrow && thread_was_interrupted)
+ {
+ throw boost::thread_interrupted();
+ }
+#endif
+ if(rethrow && exception)
+ {
+ boost::rethrow_exception(exception);
+ }
}
+ }
}
+ virtual void wait(bool rethrow=true)
+ {
+ boost::unique_lock<boost::mutex> lock(mutex);
+ wait_internal(lock, rethrow);
+ }
+
+#if defined BOOST_THREAD_USES_DATETIME
bool timed_wait_until(boost::system_time const& target_time)
{
boost::unique_lock<boost::mutex> lock(mutex);
+ if (is_deferred_)
+ return false;
+
do_callback(lock);
while(!done)
{
@@ -312,7 +383,7 @@ namespace boost
}
return true;
}
-
+#endif
#ifdef BOOST_THREAD_USES_CHRONO
template <class Clock, class Duration>
@@ -320,6 +391,8 @@ namespace boost
wait_until(const chrono::time_point<Clock, Duration>& abs_time)
{
boost::unique_lock<boost::mutex> lock(mutex);
+ if (is_deferred_)
+ return future_status::deferred;
do_callback(lock);
while(!done)
{
@@ -332,63 +405,166 @@ namespace boost
return future_status::ready;
}
#endif
- void mark_exceptional_finish_internal(boost::exception_ptr const& e)
+ void mark_exceptional_finish_internal(boost::exception_ptr const& e, boost::unique_lock<boost::mutex>& lock)
{
exception=e;
- mark_finished_internal();
+ mark_finished_internal(lock);
}
+
void mark_exceptional_finish()
{
- boost::lock_guard<boost::mutex> lock(mutex);
- mark_exceptional_finish_internal(boost::current_exception());
+ boost::unique_lock<boost::mutex> lock(mutex);
+ mark_exceptional_finish_internal(boost::current_exception(), lock);
}
+
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
void mark_interrupted_finish()
{
- boost::lock_guard<boost::mutex> lock(mutex);
+ boost::unique_lock<boost::mutex> lock(mutex);
thread_was_interrupted=true;
- mark_finished_internal();
+ mark_finished_internal(lock);
}
- bool has_value()
+
+ void set_interrupted_at_thread_exit()
+ {
+ unique_lock<boost::mutex> lk(mutex);
+ thread_was_interrupted=true;
+ if (has_value(lk))
+ {
+ throw_exception(promise_already_satisfied());
+ }
+ detail::make_ready_at_thread_exit(shared_from_this());
+ }
+#endif
+
+ void set_exception_at_thread_exit(exception_ptr e)
+ {
+ unique_lock<boost::mutex> lk(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(mutex);
- return done && !(exception || thread_was_interrupted);
+ return done && !(exception
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ || thread_was_interrupted
+#endif
+ );
+ }
+
+ bool has_value(unique_lock<boost::mutex>& ) const
+ {
+ return done && !(exception
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ || thread_was_interrupted
+#endif
+ );
}
- bool has_exception()
+
+ bool has_exception() const
{
boost::lock_guard<boost::mutex> lock(mutex);
- return done && (exception || thread_was_interrupted);
+ return done && (exception
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ || thread_was_interrupted
+#endif
+ );
+ }
+
+ bool has_exception(unique_lock<boost::mutex>&) const
+ {
+ return done && (exception
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ || thread_was_interrupted
+#endif
+ );
+ }
+
+ bool is_deferred(boost::lock_guard<boost::mutex>&) const {
+ return is_deferred_;
+ }
+
+ launch launch_policy(boost::unique_lock<boost::mutex>&) const
+ {
+ return policy_;
+ }
+
+ future_state::state get_state() const
+ {
+ boost::lock_guard<boost::mutex> guard(mutex);
+ if(!done)
+ {
+ return future_state::waiting;
+ }
+ else
+ {
+ return future_state::ready;
+ }
+ }
+
+ exception_ptr get_exception_ptr()
+ {
+ boost::unique_lock<boost::mutex> lock(mutex);
+ return get_exception_ptr(lock);
+ }
+ exception_ptr get_exception_ptr(boost::unique_lock<boost::mutex>& lock)
+ {
+ wait_internal(lock, false);
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ if(thread_was_interrupted)
+ {
+ return copy_exception(boost::thread_interrupted());
+ }
+#endif
+ return exception;
}
template<typename F,typename U>
void set_wait_callback(F f,U* u)
{
+ boost::lock_guard<boost::mutex> lock(mutex);
callback=boost::bind(f,boost::ref(*u));
}
+ virtual void execute(boost::unique_lock<boost::mutex>&) {}
+
private:
- future_object_base(future_object_base const&);
- future_object_base& operator=(future_object_base const&);
+ shared_state_base(shared_state_base const&);
+ shared_state_base& operator=(shared_state_base const&);
};
template<typename T>
struct future_traits
{
- typedef boost::scoped_ptr<T> storage_type;
+ typedef boost::scoped_ptr<T> storage_type;
+ struct dummy;
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
- typedef T const& source_reference_type;
- struct dummy;
- typedef typename boost::mpl::if_<boost::is_fundamental<T>,dummy&,BOOST_THREAD_RV_REF(T)>::type rvalue_source_type;
- typedef typename boost::mpl::if_<boost::is_fundamental<T>,T,BOOST_THREAD_RV_REF(T)>::type move_dest_type;
+ typedef T const& source_reference_type;
+ //typedef typename conditional<boost::is_fundamental<T>::value,dummy&,BOOST_THREAD_RV_REF(T)>::type rvalue_source_type;
+ typedef BOOST_THREAD_RV_REF(T) rvalue_source_type;
+ //typedef typename conditional<boost::is_fundamental<T>::value,T,BOOST_THREAD_RV_REF(T)>::type move_dest_type;
+ typedef T move_dest_type;
#elif defined BOOST_THREAD_USES_MOVE
- typedef T& source_reference_type;
- typedef typename boost::mpl::if_<boost::has_move_emulation_enabled<T>,BOOST_THREAD_RV_REF(T),T const&>::type rvalue_source_type;
- typedef typename boost::mpl::if_<boost::has_move_emulation_enabled<T>,BOOST_THREAD_RV_REF(T),T>::type move_dest_type;
+ typedef typename conditional<boost::is_fundamental<T>::value,T,T&>::type source_reference_type;
+ //typedef typename conditional<boost::is_fundamental<T>::value,T,BOOST_THREAD_RV_REF(T)>::type rvalue_source_type;
+ //typedef typename conditional<boost::enable_move_utility_emulation<T>::value,BOOST_THREAD_RV_REF(T),T>::type move_dest_type;
+ typedef BOOST_THREAD_RV_REF(T) rvalue_source_type;
+ typedef T move_dest_type;
#else
- typedef T& source_reference_type;
- typedef typename boost::mpl::if_<boost::is_convertible<T&,BOOST_THREAD_RV_REF(T) >,BOOST_THREAD_RV_REF(T),T const&>::type rvalue_source_type;
- typedef typename boost::mpl::if_<boost::is_convertible<T&,BOOST_THREAD_RV_REF(T) >,BOOST_THREAD_RV_REF(T),T>::type move_dest_type;
+ 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;
static void init(storage_type& storage,source_reference_type t)
@@ -398,7 +574,11 @@ namespace boost
static void init(storage_type& storage,rvalue_source_type t)
{
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ storage.reset(new T(boost::forward<T>(t)));
+#else
storage.reset(new T(static_cast<rvalue_source_type>(t)));
+#endif
}
static void cleanup(storage_type& storage)
@@ -412,8 +592,8 @@ namespace boost
{
typedef T* storage_type;
typedef T& source_reference_type;
- struct rvalue_source_type
- {};
+ //struct rvalue_source_type
+ //{};
typedef T& move_dest_type;
typedef T& shared_future_get_result_type;
@@ -447,9 +627,10 @@ namespace boost
};
+ // Used to create stand-alone futures
template<typename T>
- struct future_object:
- detail::future_object_base
+ struct shared_state:
+ detail::shared_state_base
{
typedef typename future_traits<T>::storage_type storage_type;
typedef typename future_traits<T>::source_reference_type source_reference_type;
@@ -459,117 +640,424 @@ namespace boost
storage_type result;
- future_object():
+ shared_state():
result(0)
{}
- void mark_finished_with_result_internal(source_reference_type result_)
+ ~shared_state()
+ {}
+
+ void mark_finished_with_result_internal(source_reference_type result_, boost::unique_lock<boost::mutex>& lock)
{
future_traits<T>::init(result,result_);
- mark_finished_internal();
+ this->mark_finished_internal(lock);
}
- void mark_finished_with_result_internal(rvalue_source_type result_)
+ void mark_finished_with_result_internal(rvalue_source_type result_, boost::unique_lock<boost::mutex>& lock)
{
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ future_traits<T>::init(result,boost::forward<T>(result_));
+#else
future_traits<T>::init(result,static_cast<rvalue_source_type>(result_));
- mark_finished_internal();
+#endif
+ this->mark_finished_internal(lock);
}
void mark_finished_with_result(source_reference_type result_)
{
- boost::lock_guard<boost::mutex> lock(mutex);
- mark_finished_with_result_internal(result_);
+ boost::unique_lock<boost::mutex> lock(mutex);
+ this->mark_finished_with_result_internal(result_, lock);
}
void mark_finished_with_result(rvalue_source_type result_)
{
- boost::lock_guard<boost::mutex> lock(mutex);
- mark_finished_with_result_internal(static_cast<rvalue_source_type>(result_));
+ boost::unique_lock<boost::mutex> lock(mutex);
+
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ mark_finished_with_result_internal(boost::forward<T>(result_), lock);
+#else
+ mark_finished_with_result_internal(static_cast<rvalue_source_type>(result_), lock);
+#endif
}
- move_dest_type get()
+ virtual move_dest_type get()
{
- wait();
- return static_cast<move_dest_type>(*result);
+ boost::unique_lock<boost::mutex> lock(mutex);
+ wait_internal(lock);
+ return boost::move(*result);
}
- shared_future_get_result_type get_sh()
+ virtual shared_future_get_result_type get_sh()
{
- wait();
- return static_cast<shared_future_get_result_type>(*result);
+ boost::unique_lock<boost::mutex> lock(mutex);
+ wait_internal(lock);
+ return *result;
}
- future_state::state get_state()
+ //void set_value_at_thread_exit(const T & result_)
+ void set_value_at_thread_exit(source_reference_type result_)
{
- boost::lock_guard<boost::mutex> guard(mutex);
- if(!done)
- {
- return future_state::waiting;
- }
- else
- {
- return future_state::ready;
- }
+ unique_lock<boost::mutex> lk(this->mutex);
+ if (this->has_value(lk))
+ {
+ throw_exception(promise_already_satisfied());
+ }
+ //future_traits<T>::init(result,result_);
+ result.reset(new T(result_));
+
+ this->is_constructed = true;
+ detail::make_ready_at_thread_exit(shared_from_this());
+ }
+ //void set_value_at_thread_exit(BOOST_THREAD_RV_REF(T) result_)
+ 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());
+ result.reset(new T(boost::move(result_)));
+ //future_traits<T>::init(result,static_cast<rvalue_source_type>(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<typename T>
+ struct shared_state<T&>:
+ detail::shared_state_base
+ {
+ typedef typename future_traits<T&>::storage_type storage_type;
+ typedef typename future_traits<T&>::source_reference_type source_reference_type;
+ typedef typename future_traits<T&>::move_dest_type move_dest_type;
+ typedef typename future_traits<T&>::shared_future_get_result_type shared_future_get_result_type;
+
+ T* result;
+
+ shared_state():
+ result(0)
+ {}
+
+ ~shared_state()
+ {
+ }
+
+ void mark_finished_with_result_internal(source_reference_type result_, boost::unique_lock<boost::mutex>& lock)
+ {
+ //future_traits<T>::init(result,result_);
+ result= &result_;
+ mark_finished_internal(lock);
+ }
+
+ void mark_finished_with_result(source_reference_type result_)
+ {
+ boost::unique_lock<boost::mutex> lock(mutex);
+ mark_finished_with_result_internal(result_, lock);
+ }
+
+ virtual T& get()
+ {
+ boost::unique_lock<boost::mutex> lock(mutex);
+ wait_internal(lock);
+ return *result;
+ }
+
+ virtual T& get_sh()
+ {
+ boost::unique_lock<boost::mutex> lock(mutex);
+ wait_internal(lock);
+ return *result;
+ }
+
+ 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());
+ //future_traits<T>::init(result,result_);
+ result= &result_;
+ this->is_constructed = true;
+ detail::make_ready_at_thread_exit(shared_from_this());
}
private:
- future_object(future_object const&);
- future_object& operator=(future_object const&);
+ shared_state(shared_state const&);
+ shared_state& operator=(shared_state const&);
};
template<>
- struct future_object<void>:
- detail::future_object_base
+ struct shared_state<void>:
+ detail::shared_state_base
{
typedef void shared_future_get_result_type;
- future_object()
+ shared_state()
{}
- void mark_finished_with_result_internal()
+ void mark_finished_with_result_internal(boost::unique_lock<boost::mutex>& lock)
{
- mark_finished_internal();
+ mark_finished_internal(lock);
}
void mark_finished_with_result()
{
- boost::lock_guard<boost::mutex> lock(mutex);
- mark_finished_with_result_internal();
+ boost::unique_lock<boost::mutex> lock(mutex);
+ mark_finished_with_result_internal(lock);
}
- void get()
+ virtual void get()
{
- wait();
+ boost::unique_lock<boost::mutex> lock(mutex);
+ this->wait_internal(lock);
}
- void get_sh()
+
+ virtual void get_sh()
{
- wait();
+ boost::unique_lock<boost::mutex> lock(mutex);
+ this->wait_internal(lock);
}
- future_state::state get_state()
+
+ void set_value_at_thread_exit()
{
- boost::lock_guard<boost::mutex> guard(mutex);
- if(!done)
- {
- return future_state::waiting;
- }
- else
- {
- return future_state::ready;
- }
+ 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:
- future_object(future_object const&);
- future_object& operator=(future_object const&);
+ 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:
+ boost::thread thr_;
+ void join()
+ {
+ if (thr_.joinable()) thr_.join();
+ }
+ public:
+ future_async_shared_state_base()
+ {
+ this->set_async();
+ }
+ explicit future_async_shared_state_base(BOOST_THREAD_RV_REF(boost::thread) th) :
+ thr_(boost::move(th))
+ {
+ this->set_async();
+ }
+
+ ~future_async_shared_state_base()
+ {
+ join();
+ }
+
+ virtual void wait(bool rethrow)
+ {
+ join();
+ this->base_type::wait(rethrow);
+ }
+ };
+
+ /////////////////////////
+ /// future_async_shared_state
+ /////////////////////////
+ template<typename Rp, typename Fp>
+ struct future_async_shared_state: future_async_shared_state_base<Rp>
+ {
+ typedef future_async_shared_state_base<Rp> base_type;
+
+ public:
+ explicit future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f) :
+ base_type(thread(&future_async_shared_state::run, this, boost::forward<Fp>(f)))
+ {
+ }
+
+ static void run(future_async_shared_state* that, BOOST_THREAD_FWD_REF(Fp) f)
+ {
+ try
+ {
+ that->mark_finished_with_result(f());
+ }
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ catch(thread_interrupted& )
+ {
+ that->mark_interrupted_finish();
+ }
+#endif
+ catch(...)
+ {
+ that->mark_exceptional_finish();
+ }
+ }
+ };
+
+ template<typename Fp>
+ struct future_async_shared_state<void, Fp>: public future_async_shared_state_base<void>
+ {
+ typedef future_async_shared_state_base<void> base_type;
+
+ public:
+ explicit future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f) :
+ base_type(thread(&future_async_shared_state::run, this, boost::forward<Fp>(f)))
+ {
+ }
+
+ static void run(future_async_shared_state* that, BOOST_THREAD_FWD_REF(Fp) f)
+ {
+ try
+ {
+ f();
+ that->mark_finished_with_result();
+ }
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ catch(thread_interrupted& )
+ {
+ that->mark_interrupted_finish();
+ }
+#endif
+ catch(...)
+ {
+ that->mark_exceptional_finish();
+ }
+ }
+ };
+
+ template<typename Rp, typename Fp>
+ struct future_async_shared_state<Rp&, Fp>: future_async_shared_state_base<Rp&>
+ {
+ typedef future_async_shared_state_base<Rp&> base_type;
+
+ public:
+ explicit future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f) :
+ base_type(thread(&future_async_shared_state::run, this, boost::forward<Fp>(f)))
+ {
+ }
+
+ static void run(future_async_shared_state* that, BOOST_THREAD_FWD_REF(Fp) f)
+ {
+ try
+ {
+ that->mark_finished_with_result(f());
+ }
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ catch(thread_interrupted& )
+ {
+ that->mark_interrupted_finish();
+ }
+#endif
+ 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::forward<Fp>(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::forward<Fp>(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::forward<Fp>(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);
+ }
+ }
};
// template<typename T, typename Allocator>
-// struct future_object_alloc: public future_object<T>
+// struct shared_state_alloc: public shared_state<T>
// {
-// typedef future_object<T> base;
+// typedef shared_state<T> base;
// Allocator alloc_;
//
// public:
-// explicit future_object_alloc(const Allocator& a)
+// explicit shared_state_alloc(const Allocator& a)
// : alloc_(a) {}
//
// };
@@ -580,38 +1068,33 @@ namespace boost
struct registered_waiter
{
- boost::shared_ptr<detail::future_object_base> future_;
- detail::future_object_base::waiter_list::iterator wait_iterator;
+ boost::shared_ptr<detail::shared_state_base> future_;
+ detail::shared_state_base::waiter_list::iterator wait_iterator;
count_type index;
- registered_waiter(boost::shared_ptr<detail::future_object_base> const& a_future,
- detail::future_object_base::waiter_list::iterator wait_iterator_,
+ registered_waiter(boost::shared_ptr<detail::shared_state_base> const& a_future,
+ detail::shared_state_base::waiter_list::iterator wait_iterator_,
count_type index_):
future_(a_future),wait_iterator(wait_iterator_),index(index_)
{}
-
};
struct all_futures_lock
{
#ifdef _MANAGED
- typedef std::ptrdiff_t count_type_portable;
+ typedef std::ptrdiff_t count_type_portable;
#else
- typedef count_type count_type_portable;
+ typedef count_type count_type_portable;
#endif
- count_type_portable count;
- boost::scoped_array<boost::unique_lock<boost::mutex> > locks;
+ 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)
{
-#if defined __DECCXX || defined __SUNPRO_CC || defined __hpux
- locks[i]=boost::unique_lock<boost::mutex>(futures[i].future_->mutex).move();
-#else
- locks[i]=boost::unique_lock<boost::mutex>(futures[i].future_->mutex);
-#endif
+ locks[i]=BOOST_THREAD_MAKE_RV_REF(boost::unique_lock<boost::mutex>(futures[i].future_->mutex));
}
}
@@ -643,11 +1126,25 @@ namespace boost
{
if(f.future_)
{
- futures.push_back(registered_waiter(f.future_,f.future_->register_external_waiter(cv),future_count));
+ registered_waiter waiter(f.future_,f.future_->register_external_waiter(cv),future_count);
+ try {
+ futures.push_back(waiter);
+ } catch(...) {
+ f.future_->remove_external_waiter(waiter.wait_iterator);
+ 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);
@@ -686,18 +1183,21 @@ namespace boost
struct is_future_type
{
BOOST_STATIC_CONSTANT(bool, value=false);
+ typedef void type;
};
template<typename T>
struct is_future_type<BOOST_THREAD_FUTURE<T> >
{
BOOST_STATIC_CONSTANT(bool, value=true);
+ typedef T type;
};
template<typename T>
struct is_future_type<shared_future<T> >
{
BOOST_STATIC_CONSTANT(bool, value=true);
+ typedef T type;
};
template<typename Iterator>
@@ -709,6 +1209,7 @@ namespace boost
}
}
+#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)
{
@@ -742,6 +1243,16 @@ namespace boost
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)
template<typename Iterator>
typename boost::disable_if<is_future_type<Iterator>,Iterator>::type wait_for_any(Iterator begin,Iterator end)
@@ -757,6 +1268,7 @@ namespace boost
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>,unsigned>::type wait_for_any(F1& f1,F2& f2)
{
@@ -798,6 +1310,15 @@ namespace boost
waiter.add(f5);
return waiter.wait();
}
+#else
+ template<typename F1, typename... Fs>
+ typename boost::enable_if<is_future_type<F1>, unsigned>::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;
@@ -805,72 +1326,70 @@ namespace boost
template <typename R>
class packaged_task;
- template <typename R>
- class BOOST_THREAD_FUTURE
+ namespace detail
{
- private:
+ /// Common implementation for all the futures independently of the return type
+ class base_future
+ {
+ //BOOST_THREAD_MOVABLE(base_future)
- typedef boost::shared_ptr<detail::future_object<R> > future_ptr;
+ };
+ /// 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;
+ static //BOOST_CONSTEXPR
+ future_ptr make_exceptional_future_ptr(exceptional_ptr const& ex) {
+ promise<R> p;
+ p.set_exception(ex.ptr_);
+ return p.get_future().future_;
+ }
future_ptr future_;
- friend class shared_future<R>;
- friend class promise<R>;
- friend class packaged_task<R>;
- friend class detail::future_waiter;
+ basic_future(future_ptr a_future):
+ future_(a_future)
+ {
+ }
+ // Copy construction from a shared_future
+ explicit basic_future(const shared_future<R>&) BOOST_NOEXCEPT;
- typedef typename detail::future_traits<R>::move_dest_type move_dest_type;
+ public:
+ typedef future_state::state state;
- BOOST_THREAD_FUTURE(future_ptr a_future):
- future_(a_future)
- {}
+ BOOST_THREAD_MOVABLE(basic_future)
+ basic_future(): future_() {}
- public:
- BOOST_THREAD_MOVABLE_ONLY(BOOST_THREAD_FUTURE)
- typedef future_state::state state;
- BOOST_THREAD_FUTURE()
- {}
+ //BOOST_CONSTEXPR
+ basic_future(exceptional_ptr const& ex)
+ : future_(make_exceptional_future_ptr(ex))
+ {
+ }
- ~BOOST_THREAD_FUTURE()
- {}
+ ~basic_future() {}
- BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT:
- future_(BOOST_THREAD_RV(other).future_)
+ basic_future(BOOST_THREAD_RV_REF(basic_future) other) BOOST_NOEXCEPT:
+ future_(BOOST_THREAD_RV(other).future_)
{
BOOST_THREAD_RV(other).future_.reset();
}
-
- BOOST_THREAD_FUTURE& operator=(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT
+ 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;
}
-
- shared_future<R> share()
+ void swap(basic_future& that) BOOST_NOEXCEPT
{
- return shared_future<R>(::boost::move(*this));
- }
-
- void swap(BOOST_THREAD_FUTURE& other)
- {
- future_.swap(other.future_);
- }
-
- // retrieving the value
- move_dest_type get()
- {
- if(!future_)
- {
- boost::throw_exception(future_uninitialized());
- }
-
- return future_->get();
+ future_.swap(that.future_);
}
-
// functions to check state, and wait for ready
- state get_state() const BOOST_NOEXCEPT
+ state get_state() const
{
if(!future_)
{
@@ -879,21 +1398,34 @@ namespace boost
return future_->get_state();
}
- bool is_ready() const BOOST_NOEXCEPT
+ bool is_ready() const
{
return get_state()==future_state::ready;
}
- bool has_exception() const BOOST_NOEXCEPT
+ bool has_exception() const
{
return future_ && future_->has_exception();
}
- bool has_value() const BOOST_NOEXCEPT
+ 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);
+ }
+
+ exception_ptr get_exception_ptr()
+ {
+ return future_
+ ? future_->get_exception_ptr()
+ : exception_ptr();
+ }
+
bool valid() const BOOST_NOEXCEPT
{
return future_ != 0;
@@ -909,6 +1441,7 @@ namespace boost
future_->wait(false);
}
+#if defined BOOST_THREAD_USES_DATETIME
template<typename Duration>
bool timed_wait(Duration const& rel_time) const
{
@@ -923,6 +1456,7 @@ namespace boost
}
return future_->timed_wait_until(abs_time);
}
+#endif
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
future_status
@@ -942,177 +1476,776 @@ namespace boost
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);
+#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
+ }
+
+ 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);
+#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_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 detail::future_traits<R>::move_dest_type move_dest_type;
+ public: // when_all
+
+ 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
+
+ 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;
+ }
+
+// BOOST_THREAD_FUTURE& operator=(exceptional_ptr const& ex)
+// {
+// this->future_=base_type::make_exceptional_future_ptr(ex);
+// 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();
+ }
+
+ // retrieving the value
+ move_dest_type get()
+ {
+ if(!this->future_)
+ {
+ boost::throw_exception(future_uninitialized());
+ }
+ future_ptr fut_=this->future_;
+#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
+ this->future_.reset();
+#endif
+ return fut_->get();
+ }
+
+ 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_)
+ {
+ boost::throw_exception(future_uninitialized());
+ }
+ this->future_->wait(false);
+ future_ptr fut_=this->future_;
+#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
+ this->future_.reset();
+#endif
+ if (fut_->has_value()) {
+ return fut_->get();
+ }
+ 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_)
+ {
+ boost::throw_exception(future_uninitialized());
+ }
+ this->future_->wait(false);
+ future_ptr fut_=this->future_;
+#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
+ this->future_.reset();
+#endif
+ if (fut_->has_value()) {
+ return fut_->get();
+ }
+ else {
+ return v;
+ }
+ }
+
+
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
+
+// template<typename F>
+// auto then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
+
+//#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
+// template<typename RF>
+// inline BOOST_THREAD_FUTURE<RF> then(RF(*func)(BOOST_THREAD_FUTURE&));
+// template<typename RF>
+// inline BOOST_THREAD_FUTURE<RF> then(launch policy, RF(*func)(BOOST_THREAD_FUTURE&));
+//#endif
+ 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
+
+ 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
+
+//#if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
+// inline
+// typename boost::enable_if<
+// is_future_type<value_type>,
+// value_type
+// //BOOST_THREAD_FUTURE<typename is_future_type<value_type>::type>
+// >::type
+// unwrap();
+//#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);
+ #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_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 detail::future_traits<R>::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;
+ }
+// BOOST_THREAD_FUTURE& operator=(exceptional_ptr const& ex)
+// {
+// this->future_=base_type::make_exceptional_future_ptr(ex);
+// 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();
+ }
+
+ // retrieving the value
+ move_dest_type get()
+ {
+ if(!this->future_)
+ {
+ boost::throw_exception(future_uninitialized());
+ }
+ future_ptr fut_=this->future_;
+ #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
+ this->future_.reset();
+ #endif
+ return fut_->get();
+ }
+ move_dest_type get_or(BOOST_THREAD_RV_REF(R) v) // EXTENSION
+ {
+ if(!this->future_)
+ {
+ boost::throw_exception(future_uninitialized());
+ }
+ this->future_->wait(false);
+ future_ptr fut_=this->future_;
+ #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
+ this->future_.reset();
+ #endif
+ if (fut_->has_value()) return fut_->get();
+ else return boost::move(v);
+ }
+
+ move_dest_type get_or(R const& v) // EXTENSION
+ {
+ if(!this->future_)
+ {
+ boost::throw_exception(future_uninitialized());
+ }
+ this->future_->wait(false);
+ future_ptr fut_=this->future_;
+ #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
+ this->future_.reset();
+ #endif
+ if (fut_->has_value()) return fut_->get();
+ else return v;
+ }
+
+
+ #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
+
+ // template<typename F>
+ // auto then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
+
+ //#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
+ // template<typename RF>
+ // inline BOOST_THREAD_FUTURE<RF> then(RF(*func)(BOOST_THREAD_FUTURE&));
+ // template<typename RF>
+ // inline BOOST_THREAD_FUTURE<RF> then(launch policy, RF(*func)(BOOST_THREAD_FUTURE&));
+ //#endif
+ 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
+ #endif
+
+ #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
+ inline
+ BOOST_THREAD_FUTURE<R2>
+ unwrap(); // EXTENSION
+ #endif
+
+ };
+
template <typename R>
- class shared_future
+ class shared_future : public detail::basic_future<R>
{
- typedef boost::shared_ptr<detail::future_object<R> > future_ptr;
- future_ptr future_;
+ typedef detail::basic_future<R> base_type;
+ typedef typename base_type::future_ptr future_ptr;
friend class detail::future_waiter;
friend class promise<R>;
- friend class packaged_task<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):
- future_(a_future)
+ base_type(a_future)
{}
public:
BOOST_THREAD_MOVABLE(shared_future)
+ typedef R value_type; // EXTENSION
shared_future(shared_future const& other):
- future_(other.future_)
+ base_type(other)
{}
typedef future_state::state state;
- shared_future()
+ BOOST_CONSTEXPR shared_future()
{}
-
+ //BOOST_CONSTEXPR
+ shared_future(exceptional_ptr const& ex):
+ base_type(ex) {}
~shared_future()
{}
shared_future& operator=(shared_future const& other)
{
- future_=other.future_;
+ shared_future(other).swap(*this);
return *this;
}
+// shared_future& operator=(exceptional_ptr const& ex)
+// {
+// this->future_=base_type::make_exceptional_future_ptr(ex);
+// return *this;
+// }
+
shared_future(BOOST_THREAD_RV_REF(shared_future) other) BOOST_NOEXCEPT :
- future_(BOOST_THREAD_RV(other).future_)
+ base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
{
BOOST_THREAD_RV(other).future_.reset();
}
- shared_future(BOOST_THREAD_RV_REF_BEG BOOST_THREAD_FUTURE<R> BOOST_THREAD_RV_REF_END other) BOOST_NOEXCEPT :
- future_(BOOST_THREAD_RV(other).future_)
+ 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))))
{
- BOOST_THREAD_RV(other).future_.reset();
}
+
shared_future& operator=(BOOST_THREAD_RV_REF(shared_future) other) BOOST_NOEXCEPT
{
- future_.swap(BOOST_THREAD_RV(other).future_);
- BOOST_THREAD_RV(other).future_.reset();
+ base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
return *this;
}
- shared_future& operator=(BOOST_THREAD_RV_REF_BEG BOOST_THREAD_FUTURE<R> BOOST_THREAD_RV_REF_END other) BOOST_NOEXCEPT
+ shared_future& operator=(BOOST_THREAD_RV_REF( BOOST_THREAD_FUTURE<R> ) other) BOOST_NOEXCEPT
{
- future_.swap(BOOST_THREAD_RV(other).future_);
- BOOST_THREAD_RV(other).future_.reset();
+ base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
return *this;
}
void swap(shared_future& other) BOOST_NOEXCEPT
{
- future_.swap(other.future_);
+ static_cast<base_type*>(this)->swap(other);
}
// retrieving the value
- typename detail::future_object<R>::shared_future_get_result_type get()
+ typename detail::shared_state<R>::shared_future_get_result_type get()
{
- if(!future_)
+ if(!this->future_)
{
boost::throw_exception(future_uninitialized());
}
- return future_->get_sh();
+ return this->future_->get_sh();
}
- // functions to check state, and wait for ready
- state get_state() const BOOST_NOEXCEPT
+ 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) // EXTENSION
{
- if(!future_)
+ if(!this->future_)
{
- return future_state::uninitialized;
+ boost::throw_exception(future_uninitialized());
}
- return future_->get_state();
+ future_ptr fut_=this->future_;
+ fut_->wait();
+ if (fut_->has_value()) return fut_->get_sh();
+ else return boost::move(v);
}
- bool valid() const BOOST_NOEXCEPT
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
+
+// template<typename F>
+// auto then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
+// template<typename F>
+// auto then(launch, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
+
+//#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
+// template<typename RF>
+// inline BOOST_THREAD_FUTURE<RF> then(RF(*func)(shared_future&));
+// template<typename RF>
+// inline BOOST_THREAD_FUTURE<RF> then(launch policy, RF(*func)(shared_future&));
+//#endif
+ template<typename F>
+ inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future)>::type>
+ then(BOOST_THREAD_FWD_REF(F) func); // 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); // EXTENSION
+#endif
+//#if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
+// inline
+// typename boost::enable_if_c<
+// is_future_type<value_type>::value,
+// BOOST_THREAD_FUTURE<typename is_future_type<value_type>::type>
+// >::type
+// unwrap();
+//#endif
+
+ };
+
+ BOOST_THREAD_DCL_MOVABLE_BEG(T) shared_future<T> BOOST_THREAD_DCL_MOVABLE_END
+
+ namespace detail
+ {
+ /// Copy construction from a shared_future
+ template <typename R>
+ inline basic_future<R>::basic_future(const shared_future<R>& other) BOOST_NOEXCEPT
+ : future_(other.future_)
+ {
+ }
+ }
+
+ template <typename R>
+ class promise
+ {
+ typedef boost::shared_ptr<detail::shared_state<R> > future_ptr;
+
+ future_ptr future_;
+ bool future_obtained;
+
+ void lazy_init()
{
- return future_ != 0;
+#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
}
- bool is_ready() const BOOST_NOEXCEPT
+ public:
+ BOOST_THREAD_MOVABLE_ONLY(promise)
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+ template <class Allocator>
+ promise(boost::allocator_arg_t, Allocator a)
{
- return get_state()==future_state::ready;
+ 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)
+ {}
- bool has_exception() const BOOST_NOEXCEPT
+ ~promise()
{
- return future_ && future_->has_exception();
+ 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);
+ }
+ }
}
- bool has_value() const BOOST_NOEXCEPT
+ // Assignment
+ promise(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT :
+ future_(BOOST_THREAD_RV(rhs).future_),future_obtained(BOOST_THREAD_RV(rhs).future_obtained)
{
- return future_ && future_->has_value();
+ 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 wait() const
+ void swap(promise& other)
{
- if(!future_)
+ 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(future_uninitialized());
+ boost::throw_exception(promise_moved());
}
- future_->wait(false);
+ if (future_obtained)
+ {
+ boost::throw_exception(future_already_retrieved());
+ }
+ future_obtained=true;
+ return BOOST_THREAD_FUTURE<R>(future_);
}
- template<typename Duration>
- bool timed_wait(Duration const& rel_time) const
+ void set_value(typename detail::future_traits<R>::source_reference_type r)
{
- return timed_wait_until(boost::get_system_time()+rel_time);
+ 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);
}
- bool timed_wait_until(boost::system_time const& abs_time) const
+// void set_value(R && r);
+ void set_value(typename detail::future_traits<R>::rvalue_source_type r)
{
- if(!future_)
+ lazy_init();
+ boost::unique_lock<boost::mutex> lock(future_->mutex);
+ if(future_->done)
{
- boost::throw_exception(future_uninitialized());
+ boost::throw_exception(promise_already_satisfied());
}
- return future_->timed_wait_until(abs_time);
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ future_->mark_finished_with_result_internal(boost::forward<R>(r), lock);
+#else
+ future_->mark_finished_with_result_internal(static_cast<typename detail::future_traits<R>::rvalue_source_type>(r), lock);
+#endif
}
-#ifdef BOOST_THREAD_USES_CHRONO
- template <class Rep, class Period>
- future_status
- wait_for(const chrono::duration<Rep, Period>& rel_time) const
+ void set_exception(boost::exception_ptr p)
{
- return wait_until(chrono::steady_clock::now() + rel_time);
+ 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(copy_exception(ex));
+ }
+ // setting the result with deferred notification
+ void set_value_at_thread_exit(const R& r)
+ {
+ if (future_.get()==0)
+ {
+ boost::throw_exception(promise_moved());
+ }
+ future_->set_value_at_thread_exit(r);
+ }
+ 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));
}
- template <class Clock, class Duration>
- future_status
- wait_until(const chrono::time_point<Clock, Duration>& abs_time) const
+ void set_exception_at_thread_exit(exception_ptr e)
{
- if(!future_)
+ if (future_.get()==0)
{
- boost::throw_exception(future_uninitialized());
+ boost::throw_exception(promise_moved());
}
- return future_->wait_until(abs_time);
+ future_->set_exception_at_thread_exit(e);
+ }
+ template <typename E>
+ void set_exception_at_thread_exit(E ex)
+ {
+ set_exception_at_thread_exit(copy_exception(ex));
}
-#endif
- };
- BOOST_THREAD_DCL_MOVABLE_BEG(T) shared_future<T> BOOST_THREAD_DCL_MOVABLE_END
+ template<typename F>
+ void set_wait_callback(F f)
+ {
+ lazy_init();
+ future_->set_wait_callback(f,this);
+ }
+
+ };
template <typename R>
- class promise
+ class promise<R&>
{
- typedef boost::shared_ptr<detail::future_object<R> > future_ptr;
+ typedef boost::shared_ptr<detail::shared_state<R&> > future_ptr;
future_ptr future_;
bool future_obtained;
void lazy_init()
{
-#if defined BOOST_THREAD_PROMISE_LAZY
+#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::future_object<R>));
+ atomic_compare_exchange(&future_,&blank,future_ptr(new detail::shared_state<R&>));
}
+#include <boost/detail/atomic_redef_macros.hpp>
#endif
}
@@ -1122,19 +2255,19 @@ namespace boost
template <class Allocator>
promise(boost::allocator_arg_t, Allocator a)
{
- typedef typename Allocator::template rebind<detail::future_object<R> >::other A2;
+ 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::future_object<R>(), D(a2, 1) );
+ future_ = future_ptr(::new(a2.allocate(1)) detail::shared_state<R&>(), D(a2, 1) );
future_obtained = false;
}
#endif
promise():
-#if defined BOOST_THREAD_PROMISE_LAZY
+#if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
future_(),
#else
- future_(new detail::future_object<R>()),
+ future_(new detail::shared_state<R&>()),
#endif
future_obtained(false)
{}
@@ -1143,11 +2276,11 @@ namespace boost
{
if(future_)
{
- boost::lock_guard<boost::mutex> lock(future_->mutex);
+ boost::unique_lock<boost::mutex> lock(future_->mutex);
- if(!future_->done)
+ if(!future_->done && !future_->is_constructed)
{
- future_->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()));
+ future_->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()), lock);
}
}
}
@@ -1175,7 +2308,7 @@ namespace boost
}
// Result retrieval
- BOOST_THREAD_FUTURE<R> get_future()
+ BOOST_THREAD_FUTURE<R&> get_future()
{
lazy_init();
if (future_.get()==0)
@@ -1187,47 +2320,59 @@ namespace boost
boost::throw_exception(future_already_retrieved());
}
future_obtained=true;
- return BOOST_THREAD_FUTURE<R>(future_);
+ return BOOST_THREAD_FUTURE<R&>(future_);
}
- void set_value(typename detail::future_traits<R>::source_reference_type r)
+ void set_value(R& r)
{
lazy_init();
- boost::lock_guard<boost::mutex> lock(future_->mutex);
+ boost::unique_lock<boost::mutex> lock(future_->mutex);
if(future_->done)
{
boost::throw_exception(promise_already_satisfied());
}
- future_->mark_finished_with_result_internal(r);
+ future_->mark_finished_with_result_internal(r, lock);
}
-// void set_value(R && r);
- void set_value(typename detail::future_traits<R>::rvalue_source_type r)
+ void set_exception(boost::exception_ptr p)
{
lazy_init();
- boost::lock_guard<boost::mutex> lock(future_->mutex);
+ boost::unique_lock<boost::mutex> lock(future_->mutex);
if(future_->done)
{
boost::throw_exception(promise_already_satisfied());
}
- future_->mark_finished_with_result_internal(static_cast<typename detail::future_traits<R>::rvalue_source_type>(r));
+ future_->mark_exceptional_finish_internal(p, lock);
}
-
- void set_exception(boost::exception_ptr p)
+ template <typename E>
+ void set_exception(E ex)
{
- lazy_init();
- boost::lock_guard<boost::mutex> lock(future_->mutex);
- if(future_->done)
- {
- boost::throw_exception(promise_already_satisfied());
- }
- future_->mark_exceptional_finish_internal(p);
+ set_exception(copy_exception(ex));
}
// setting the result with deferred notification
- //void set_value_at_thread_exit(const R& r); // NOT YET IMPLEMENTED
- //void set_value_at_thread_exit(see below); // NOT YET IMPLEMENTED
- //void set_exception_at_thread_exit(exception_ptr p); // NOT YET IMPLEMENTED
+ 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(copy_exception(ex));
+ }
template<typename F>
void set_wait_callback(F f)
@@ -1237,22 +2382,21 @@ namespace boost
}
};
-
template <>
class promise<void>
{
- typedef boost::shared_ptr<detail::future_object<void> > future_ptr;
+ typedef boost::shared_ptr<detail::shared_state<void> > future_ptr;
future_ptr future_;
bool future_obtained;
void lazy_init()
{
-#if defined BOOST_THREAD_PROMISE_LAZY
+#if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
if(!atomic_load(&future_))
{
future_ptr blank;
- atomic_compare_exchange(&future_,&blank,future_ptr(new detail::future_object<void>));
+ atomic_compare_exchange(&future_,&blank,future_ptr(new detail::shared_state<void>));
}
#endif
}
@@ -1263,19 +2407,19 @@ namespace boost
template <class Allocator>
promise(boost::allocator_arg_t, Allocator a)
{
- typedef typename Allocator::template rebind<detail::future_object<void> >::other A2;
+ 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::future_object<void>(), D(a2, 1) );
+ future_ = future_ptr(::new(a2.allocate(1)) detail::shared_state<void>(), D(a2, 1) );
future_obtained = false;
}
#endif
promise():
-#if defined BOOST_THREAD_PROMISE_LAZY
+#if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
future_(),
#else
- future_(new detail::future_object<void>),
+ future_(new detail::shared_state<void>),
#endif
future_obtained(false)
{}
@@ -1284,11 +2428,11 @@ namespace boost
{
if(future_)
{
- boost::lock_guard<boost::mutex> lock(future_->mutex);
+ boost::unique_lock<boost::mutex> lock(future_->mutex);
- if(!future_->done)
+ if(!future_->done && !future_->is_constructed)
{
- future_->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()));
+ future_->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()), lock);
}
}
}
@@ -1331,29 +2475,59 @@ namespace boost
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::lock_guard<boost::mutex> lock(future_->mutex);
+ boost::unique_lock<boost::mutex> lock(future_->mutex);
if(future_->done)
{
boost::throw_exception(promise_already_satisfied());
}
- future_->mark_finished_with_result_internal();
+ future_->mark_finished_with_result_internal(lock);
}
void set_exception(boost::exception_ptr p)
{
lazy_init();
- boost::lock_guard<boost::mutex> lock(future_->mutex);
+ boost::unique_lock<boost::mutex> lock(future_->mutex);
if(future_->done)
{
boost::throw_exception(promise_already_satisfied());
}
- future_->mark_exceptional_finish_internal(p);
+ future_->mark_exceptional_finish_internal(p,lock);
+ }
+ template <typename E>
+ void set_exception(E ex)
+ {
+ set_exception(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(copy_exception(ex));
}
template<typename F>
@@ -1364,28 +2538,50 @@ namespace boost
}
};
-
+}
#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
- namespace container
+namespace boost { namespace container {
+ template <class R, class Alloc>
+ struct uses_allocator< ::boost::promise<R> , Alloc> : true_type
{
- template <class R, class Alloc>
- struct uses_allocator<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
{
- template<typename R>
- struct task_base:
- detail::future_object<R>
+#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():
+ task_base_shared_state():
started(false)
{}
@@ -1393,7 +2589,13 @@ namespace boost
{
started=false;
}
+#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);
@@ -1403,56 +2605,213 @@ namespace boost
}
started=true;
}
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ do_run(boost::forward<ArgTypes>(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::forward<ArgTypes>(args)...);
+#else
+ do_apply();
+#endif
}
void owner_destroyed()
{
- boost::lock_guard<boost::mutex> lk(this->mutex);
+ boost::unique_lock<boost::mutex> lk(this->mutex);
if(!started)
{
started=true;
- this->mark_exceptional_finish_internal(boost::copy_exception(boost::broken_promise()));
+ this->mark_exceptional_finish_internal(boost::copy_exception(boost::broken_promise()), lk);
}
}
-
- virtual void do_run()=0;
};
+#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_))
+ {}
+#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::forward<ArgTypes>(args)...));
+ }
+#else
+ void do_apply()
+ {
+ try
+ {
+ this->set_value_at_thread_exit(f());
+ }
+#endif
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ catch(thread_interrupted& )
+ {
+ this->set_interrupted_at_thread_exit();
+ }
+#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::forward<ArgTypes>(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
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ catch(thread_interrupted& )
+ {
+ this->mark_interrupted_finish();
+ }
+#endif
+ catch(...)
+ {
+ this->mark_exceptional_finish();
+ }
+ }
+ };
- template<typename R,typename F>
- struct task_object:
- task_base<R>
+#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_object(task_object&);
+ task_shared_state(task_shared_state&);
public:
F f;
- task_object(F const& f_):
+ task_shared_state(F const& f_):
f(f_)
{}
-#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
- task_object(BOOST_THREAD_RV_REF(F) f_):
- f(boost::forward<F>(f_))
- {}
-#else
- task_object(BOOST_THREAD_RV_REF(F) f_):
+ task_shared_state(BOOST_THREAD_RV_REF(F) f_):
f(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::forward<ArgTypes>(args)...));
+ }
+#else
+ void do_apply()
+ {
+ try
+ {
+ this->set_value_at_thread_exit(f());
+ }
+#endif
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ catch(thread_interrupted& )
+ {
+ this->set_interrupted_at_thread_exit();
+ }
#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::forward<ArgTypes>(args)...));
+ }
+#else
void do_run()
{
try
{
- this->mark_finished_with_result(f());
+ R& res((f()));
+ this->mark_finished_with_result(res);
}
+#endif
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
catch(thread_interrupted& )
{
this->mark_interrupted_finish();
}
+#endif
catch(...)
{
this->mark_exceptional_finish();
@@ -1460,66 +2819,258 @@ namespace boost
}
};
- template<typename R>
- struct task_object<R,R (*)()>:
- task_base<R>
+#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_object(task_object&);
+ task_shared_state(task_shared_state&);
public:
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ R (*f)(BOOST_THREAD_RV_REF(ArgTypes) ... );
+ task_shared_state(R (*f_)(BOOST_THREAD_RV_REF(ArgTypes) ... )):
+ f(f_)
+ {}
+#else
R (*f)();
- task_object(R (*f_)()):
+ task_shared_state(R (*f_)()):
f(f_)
{}
+#endif
+
+#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::forward<ArgTypes>(args)...));
+ }
+#else
+ void do_apply()
+ {
+ try
+ {
+ R r((f()));
+ this->set_value_at_thread_exit(boost::move(r));
+ }
+#endif
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ catch(thread_interrupted& )
+ {
+ this->set_interrupted_at_thread_exit();
+ }
+#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::forward<ArgTypes>(args)...));
+ }
+#else
void do_run()
{
try
{
- this->mark_finished_with_result(f());
+ R res((f()));
+ this->mark_finished_with_result(boost::move(res));
}
+#endif
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
catch(thread_interrupted& )
{
this->mark_interrupted_finish();
}
+#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)
+ R& (*f)(BOOST_THREAD_RV_REF(ArgTypes) ... );
+ task_shared_state(R& (*f_)(BOOST_THREAD_RV_REF(ArgTypes) ... )):
+ f(f_)
+ {}
+#else
+ R& (*f)();
+ task_shared_state(R& (*f_)()):
+ f(f_)
+ {}
+#endif
+
+#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::forward<ArgTypes>(args)...));
+ }
+#else
+ void do_apply()
+ {
+ try
+ {
+ this->set_value_at_thread_exit(f());
+ }
+#endif
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ catch(thread_interrupted& )
+ {
+ this->set_interrupted_at_thread_exit();
+ }
+#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::forward<ArgTypes>(args)...));
+ }
+#else
+ void do_run()
+ {
+ try
+ {
+ this->mark_finished_with_result(f());
+ }
+#endif
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ catch(thread_interrupted& )
+ {
+ this->mark_interrupted_finish();
+ }
+#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_object<void,F>:
- task_base<void>
+ struct task_shared_state<F,void>:
+ task_base_shared_state<void>
+#endif
{
private:
- task_object(task_object&);
+ task_shared_state(task_shared_state&);
public:
F f;
- task_object(F const& f_):
+ task_shared_state(F const& f_):
f(f_)
{}
-#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
- task_object(BOOST_THREAD_RV_REF(F) f_):
- f(boost::forward<F>(f_))
- {}
-#else
- task_object(BOOST_THREAD_RV_REF(F) f_):
+ task_shared_state(BOOST_THREAD_RV_REF(F) f_):
f(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::forward<ArgTypes>(args)...);
+#else
+ void do_apply()
+ {
+ try
+ {
+ f();
#endif
+ this->set_value_at_thread_exit();
+ }
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ catch(thread_interrupted& )
+ {
+ this->set_interrupted_at_thread_exit();
+ }
+#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
+ {
+ f(boost::forward<ArgTypes>(args)...);
+#else
void do_run()
{
try
{
f();
+#endif
this->mark_finished_with_result();
}
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
catch(thread_interrupted& )
{
this->mark_interrupted_finish();
}
+#endif
catch(...)
{
this->mark_exceptional_finish();
@@ -1527,43 +3078,109 @@ namespace boost
}
};
+#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_object<void,void (*)()>:
- task_base<void>
+ 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_object(task_object&);
+ task_shared_state(task_shared_state&);
public:
void (*f)();
- task_object(void (*f_)()):
+ task_shared_state(void (*f_)()):
f(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::forward<ArgTypes>(args)...);
+#else
+ void do_apply()
+ {
+ try
+ {
+ f();
+#endif
+ this->set_value_at_thread_exit();
+ }
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ catch(thread_interrupted& )
+ {
+ this->set_interrupted_at_thread_exit();
+ }
+#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
+ {
+ f(boost::forward<ArgTypes>(args)...);
+#else
void do_run()
{
try
{
f();
+#endif
this->mark_finished_with_result();
}
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
catch(thread_interrupted& )
{
this->mark_interrupted_finish();
}
+#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>
+ 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<R> > task_ptr;
- boost::shared_ptr<detail::task_base<R> > 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;
@@ -1574,294 +3191,1646 @@ namespace boost
{}
// construction and destruction
+#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
- explicit packaged_task(R(*f)()):
- task(new detail::task_object<R,R(*)()>(f)),future_obtained(false)
- {}
+#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::forward<ArgTypes>(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_RV_REF(F) f):
- task(new detail::task_object<R,
- typename remove_cv<typename remove_reference<F>::type>::type
- >(boost::forward<F>(f))),future_obtained(false)
- {}
+ 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 remove_cv<typename remove_reference<F>::type>::type FR;
+ 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):
- task(new detail::task_object<R,F>(f)),future_obtained(false)
- {}
+ 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):
- task(new detail::task_object<R,F>(boost::move(f))),future_obtained(false)
- {}
+ 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::forward<F>(f)));
+#else
+ typedef detail::task_shared_state<F,R()> task_shared_state_type;
+ task = task_ptr(new task_shared_state_type(boost::move(f))); // TODO forward
+#endif
+#else
+ typedef detail::task_shared_state<F,R> task_shared_state_type;
+ task = task_ptr(new task_shared_state_type(boost::forward<F>(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)();
- typedef typename Allocator::template rebind<detail::task_object<R,FR> >::other A2;
+#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)) detail::task_object<R,FR>(f), D(a2, 1) );
+ task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(f), D(a2, 1) );
future_obtained = false;
}
-#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+#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_RV_REF(F) f)
+ packaged_task(boost::allocator_arg_t, Allocator a, BOOST_THREAD_FWD_REF(F) f)
{
- typedef typename remove_cv<typename remove_reference<F>::type>::type FR;
- typedef typename Allocator::template rebind<detail::task_object<R,FR> >::other A2;
+ //typedef typename remove_cv<typename remove_reference<F>::type>::type FR;
+ 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)) detail::task_object<R,FR>(boost::forward<F>(f)), D(a2, 1) );
+ task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(boost::forward<F>(f)), D(a2, 1) );
future_obtained = false;
}
-#else
+#else // ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
template <class F, class Allocator>
packaged_task(boost::allocator_arg_t, Allocator a, const F& f)
{
- typedef typename Allocator::template rebind<detail::task_object<R,F> >::other A2;
+#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)) detail::task_object<R,F>(f), D(a2, 1) );
+ 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)
{
- typedef typename Allocator::template rebind<detail::task_object<R,F> >::other A2;
+#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)) detail::task_object<R,F>(boost::move(f)), D(a2, 1) );
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(boost::forward<F>(f)), D(a2, 1) );
+#else
+ task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(boost::move(f)), D(a2, 1) ); // TODO forward
+#endif
future_obtained = false;
}
+
#endif //BOOST_NO_CXX11_RVALUE_REFERENCES
#endif // BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
- ~packaged_task()
- {
- if(task)
- {
+ ~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)
- {
+ 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
- {
+ packaged_task& operator=(BOOST_THREAD_RV_REF(packaged_task) other) BOOST_NOEXCEPT {
+
+ // todo use forward
+#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;
}
- void reset()
- {
+ void reset() {
if (!valid())
throw future_error(system::make_error_code(future_errc::no_state));
task->reset();
future_obtained=false;
}
- void swap(packaged_task& other) BOOST_NOEXCEPT
- {
+ void swap(packaged_task& other) BOOST_NOEXCEPT {
task.swap(other.task);
std::swap(future_obtained,other.future_obtained);
}
- bool valid() const BOOST_NOEXCEPT
- {
+ bool valid() const BOOST_NOEXCEPT {
return task.get()!=0;
}
// result retrieval
- BOOST_THREAD_FUTURE<R> get_future()
- {
- if(!task)
- {
+ BOOST_THREAD_FUTURE<R> get_future() {
+ if(!task) {
boost::throw_exception(task_moved());
- }
- else if(!future_obtained)
- {
+ } else if(!future_obtained) {
future_obtained=true;
return BOOST_THREAD_FUTURE<R>(task);
- }
- else
- {
+ } else {
boost::throw_exception(future_already_retrieved());
}
- return BOOST_THREAD_FUTURE<R>();
-
}
-
// execution
- void operator()()
- {
- if(!task)
- {
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ void operator()(BOOST_THREAD_RV_REF(ArgTypes)... args) {
+ if(!task) {
+ boost::throw_exception(task_moved());
+ }
+ task->run(boost::forward<ArgTypes>(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::forward<ArgTypes>(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)
- {
+ void set_wait_callback(F f) {
task->set_wait_callback(f,this);
}
-
};
-
+}
#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
- namespace container
- {
- template <class R, class Alloc>
- struct uses_allocator<packaged_task<R>, Alloc>
- : public true_type {};
- }
+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
- BOOST_THREAD_DCL_MOVABLE_BEG(T) packaged_task<T> BOOST_THREAD_DCL_MOVABLE_END
+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);
+ }
- template <class R>
- BOOST_THREAD_FUTURE<R>
- async(launch policy, R(*f)())
- {
- if (int(policy) & int(launch::async))
- {
- packaged_task<R> pt( f );
+ ////////////////////////////////
+ // 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>(boost::forward<Fp>(f)));
+ return BOOST_THREAD_FUTURE<Rp>(h);
+ }
+}
- BOOST_THREAD_FUTURE<R> ret = pt.get_future();
- boost::thread( boost::move(pt) ).detach();
- return ::boost::move(ret);
- }
- else if (int(policy) & int(launch::deferred))
- {
- packaged_task<R> pt( f );
+ ////////////////////////////////
+ // 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(
+ 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);
+ }
+ }
- BOOST_THREAD_FUTURE<R> ret = pt.get_future();
- return ::boost::move(ret);
- } else {
- 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 typename boost::result_of<typename decay<F>::type(
+ typename decay<ArgTypes>::type...
+ )>::type R;
+ 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);
+ }
+ }
- template <class R>
- BOOST_THREAD_FUTURE<R>
- async(R(*f)())
- {
- return async(launch::any, f);
- }
-#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
- template <class F>
- BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type()>::type>
- async(launch policy, BOOST_THREAD_FWD_REF(F) f)
+#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 typename boost::result_of<typename decay<F>::type()>::type R;
- if (int(policy) & int(launch::async))
- {
- packaged_task<R> pt( boost::forward<F>(f) );
+ shared_state<Rp>* that;
+ Fp f_;
+ public:
- BOOST_THREAD_FUTURE<R> ret = pt.get_future();
- boost::thread( boost::move(pt) ).detach();
- return ::boost::move(ret);
+ shared_state_nullary_task(shared_state<Rp>* st, BOOST_THREAD_FWD_REF(Fp) f)
+ : that(st), f_(boost::forward<Fp>(f))
+ {};
+#if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ BOOST_THREAD_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_COPY_ASSIGN_REF(shared_state_nullary_task) x) //BOOST_NOEXCEPT
+ {
+ if (this != &x) {
+ that=x.that;
+ f_=x.f_;
}
- else if (int(policy) & int(launch::deferred))
- {
- packaged_task<R> pt( boost::forward<F>(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=0;
+ }
+ 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=0;
+ }
+ return *this;
+ }
+#endif
+ void operator()() {
+ try {
+ that->mark_finished_with_result(f_());
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ } catch(thread_interrupted& ) {
+ that->mark_interrupted_finish();
+#endif // defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ } catch(...) {
+ that->mark_exceptional_finish();
+ }
+
+ }
+ };
- BOOST_THREAD_FUTURE<R> ret = pt.get_future();
- return ::boost::move(ret);
- } else {
- BOOST_THREAD_FUTURE<R> ret;
- return ::boost::move(ret);
+ template<typename Fp>
+ struct shared_state_nullary_task<void, Fp>
+ {
+ shared_state<void>* that;
+ Fp f_;
+ public:
+ shared_state_nullary_task(shared_state<void>* st, BOOST_THREAD_FWD_REF(Fp) f)
+ : that(st), f_(boost::forward<Fp>(f))
+ {};
+#if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ BOOST_THREAD_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_COPY_ASSIGN_REF(shared_state_nullary_task) x) //BOOST_NOEXCEPT
+ {
+ if (this != &x) {
+ that=x.that;
+ f_=x.f_;
}
- }
- template <class F>
- BOOST_THREAD_FUTURE<typename boost::result_of<F()>::type>
- async(BOOST_THREAD_RV_REF(F) 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=0;
+ }
+ 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=0;
+ }
+ return *this;
+ }
+#endif
+ void operator()() {
+ try {
+ f_();
+ that->mark_finished_with_result();
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ } catch(thread_interrupted& ) {
+ that->mark_interrupted_finish();
+#endif // defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ } catch(...) {
+ that->mark_exceptional_finish();
+ }
+ }
+ };
+
+ template<typename Rp, typename Fp>
+ struct shared_state_nullary_task<Rp&, Fp>
{
- return async(launch::any, boost::forward<F>(f));
+ shared_state<Rp&>* that;
+ Fp f_;
+ public:
+ shared_state_nullary_task(shared_state<Rp&>* st, BOOST_THREAD_FWD_REF(Fp) f)
+ : that(st), f_(boost::forward<Fp>(f))
+ {}
+#if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ BOOST_THREAD_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_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=0;
+ }
+ 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=0;
+ }
+ return *this;
+ }
+#endif
+ void operator()() {
+ try {
+ that->mark_finished_with_result(f_());
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ } catch(thread_interrupted& ) {
+ that->mark_interrupted_finish();
+#endif // defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ } catch(...) {
+ that->mark_exceptional_finish();
+ }
+ }
+ };
+
+ /////////////////////////
+ /// future_executor_shared_state_base
+ /////////////////////////
+ template<typename Rp, typename Executor>
+ struct future_executor_shared_state: shared_state<Rp>
+ {
+ typedef shared_state<Rp> base_type;
+ protected:
+ public:
+ template<typename Fp>
+ future_executor_shared_state(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f) {
+ this->set_executor();
+ shared_state_nullary_task<Rp,Fp> t(this, boost::forward<Fp>(f));
+ ex.submit(boost::move(t));
+ }
+
+ ~future_executor_shared_state() {
+ this->wait(false);
+ }
+ };
+
+ ////////////////////////////////
+ // 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, Executor> >
+ h(new future_executor_shared_state<Rp, Executor>(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_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(
+ thread_detail::decay_copy(boost::forward<F>(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))...
+ )
+ ));
+ }
+
+// template <class R, 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_ret<R, 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_RV_REF(F) f) {
+ return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), boost::forward<F>(f)));
+ }
+#endif
-// template <class F>
-// BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type()>::type>
-// async(launch policy, F const& f)
-// {
-// typedef typename boost::result_of<typename decay<F>::type()>::type R;
-// if (int(policy) & int(launch::async))
-// {
-// packaged_task<R> pt( f );
+ ////////////////////////////////
+ // 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
+ ////////////////////////////////
+ template <typename T>
+ BOOST_THREAD_FUTURE<typename decay<T>::type> make_ready_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());
+ }
+
+ 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_THREAD_USES_MOVE
+ inline BOOST_THREAD_FUTURE<void> make_ready_future() {
+ promise<void> p;
+ p.set_value();
+ return BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ }
+#endif
+
+ template <typename T>
+ BOOST_THREAD_FUTURE<T> make_ready_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_ready_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(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());
+ }
+
+#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());
+ }
+
+// ////////////////////////////////
+// // make_ready_shared_future
+// ////////////////////////////////
+// template <typename T>
+// shared_future<typename decay<T>::type> make_ready_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 p.get_future().share();
+// }
//
-// BOOST_THREAD_FUTURE<R> ret = pt.get_future();
-// boost::thread( boost::move(pt) ).detach();
-// return ::boost::move(ret);
-// }
-// else if (int(policy) & int(launch::deferred))
-// {
-// packaged_task<R> pt( f );
//
-// BOOST_THREAD_FUTURE<R> ret = pt.get_future();
-// return ::boost::move(ret);
-// } else {
-// BOOST_THREAD_FUTURE<R> ret;
-// return ::boost::move(ret);
-// }
+// inline shared_future<void> make_ready_shared_future()
+// {
+// promise<void> p;
+// return BOOST_THREAD_MAKE_RV_REF(p.get_future().share());
+//
+// }
+//
+// ////////////////////////////////
+// // make_exceptional_shared_future
+// ////////////////////////////////
+// template <typename T>
+// shared_future<T> make_exceptional_shared_future(exception_ptr ex)
+// {
+// promise<T> p;
+// p.set_exception(ex);
+// return p.get_future().share();
+// }
+
+ ////////////////////////////////
+ // detail::future_async_continuation_shared_state
+ ////////////////////////////////
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
+namespace detail
+{
+
+ /////////////////////////
+ /// future_async_continuation_shared_state
+ /////////////////////////
+
+ template<typename F, typename Rp, typename Fp>
+ struct future_async_continuation_shared_state: future_async_shared_state_base<Rp>
+ {
+ F parent;
+ Fp continuation;
+
+ public:
+ future_async_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
+ : parent(boost::move(f)),
+ continuation(boost::move(c)) {
+ }
+
+ void launch_continuation(boost::unique_lock<boost::mutex>& ) {
+ //lock.unlock();
+ this->thr_ = thread(&future_async_continuation_shared_state::run, this);
+ }
+
+ static void run(future_async_continuation_shared_state* that) {
+ try {
+ that->mark_finished_with_result(that->continuation(boost::move(that->parent)));
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ } catch(thread_interrupted& ) {
+ that->mark_interrupted_finish();
+#endif
+ } catch(...) {
+ that->mark_exceptional_finish();
+ }
+ }
+
+ ~future_async_continuation_shared_state() {
+ this->join();
+ }
+ };
+
+ template<typename F, typename Fp>
+ struct future_async_continuation_shared_state<F, void, Fp>: public future_async_shared_state_base<void>
+ {
+ F parent;
+ Fp continuation;
+
+ public:
+ future_async_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
+ : parent(boost::move(f)),
+ continuation(boost::move(c)) {
+ }
+
+ void launch_continuation(boost::unique_lock<boost::mutex>& ) {
+ //lk.unlock();
+ this->thr_ = thread(&future_async_continuation_shared_state::run, this);
+ }
+
+ static void run(future_async_continuation_shared_state* that) {
+ try {
+ that->continuation(boost::move(that->parent));
+ that->mark_finished_with_result();
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ } catch(thread_interrupted& ) {
+ that->mark_interrupted_finish();
+#endif
+ } catch(...) {
+ that->mark_exceptional_finish();
+ }
+ }
+
+ ~future_async_continuation_shared_state() {
+ this->join();
+ }
+ };
+
+ //////////////////////////
+ /// future_deferred_continuation_shared_state
+ //////////////////////////
+ template<typename F, typename Rp, typename Fp>
+ struct future_deferred_continuation_shared_state: shared_state<Rp>
+ {
+ F parent;
+ Fp continuation;
+
+ public:
+ future_deferred_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
+ : parent(boost::move(f)),
+ continuation(boost::move(c)) {
+ this->set_deferred();
+ }
+
+ virtual void launch_continuation(boost::unique_lock<boost::mutex>& ) {
+ //execute(lk);
+ }
+
+ virtual void execute(boost::unique_lock<boost::mutex>& lck) {
+ try {
+ Fp local_fuct=boost::move(continuation);
+ F ftmp = boost::move(parent);
+ relocker relock(lck);
+ Rp res = local_fuct(boost::move(ftmp));
+ relock.lock();
+ this->mark_finished_with_result_internal(boost::move(res), lck);
+ } catch (...) {
+ this->mark_exceptional_finish_internal(current_exception(), lck);
+ }
+ }
+ };
+
+ template<typename F, typename Fp>
+ struct future_deferred_continuation_shared_state<F,void,Fp>: shared_state<void>
+ {
+ F parent;
+ Fp continuation;
+
+ public:
+ future_deferred_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
+ : parent(boost::move(f)),
+ continuation(boost::move(c)) {
+ this->set_deferred();
+ }
+
+ virtual void launch_continuation(boost::unique_lock<boost::mutex>& ) {
+ //execute(lk);
+ }
+ virtual void execute(boost::unique_lock<boost::mutex>& lck) {
+ try {
+ Fp local_fuct=boost::move(continuation);
+ F ftmp = boost::move(parent);
+ relocker relock(lck);
+ local_fuct(boost::move(ftmp));
+ relock.lock();
+ this->mark_finished_with_result_internal(lck);
+ } catch (...) {
+ this->mark_exceptional_finish_internal(current_exception(), lck);
+ }
+ }
+ };
+
+ ////////////////////////////////
+ // 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) {
+ shared_ptr<future_deferred_continuation_shared_state<F, Rp, Fp> >
+ h(new future_deferred_continuation_shared_state<F, Rp, Fp>(boost::move(f), boost::forward<Fp>(c)));
+ h->parent.future_->set_continuation_ptr(h, 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) {
+ shared_ptr<future_async_continuation_shared_state<F,Rp, Fp> >
+ h(new future_async_continuation_shared_state<F,Rp, Fp>(boost::move(f), boost::forward<Fp>(c)));
+ h->parent.future_->set_continuation_ptr(h, lock);
+
+ return BOOST_THREAD_FUTURE<Rp>(h);
+ }
+}
+
+ ////////////////////////////////
+ // template<typename F>
+ // auto 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(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());
+
+ 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_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
+ 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, F>(
+ 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, F>(
+ lock, boost::move(*this), boost::forward<F>(func)
+ )));
+ }
+ }
+
+ 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) {
+ typedef typename boost::result_of<F(BOOST_THREAD_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>(this->launch_policy(lock)) & int(launch::async)) {
+ return boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
+ lock, boost::move(*this), boost::forward<F>(func)
+ );
+ } else if (underlying_cast<int>(this->launch_policy(lock)) & int(launch::deferred)) {
+ this->future_->wait_internal(lock);
+ return boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
+ lock, boost::move(*this), boost::forward<F>(func)
+ );
+ } else {
+ return boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
+ lock, boost::move(*this), boost::forward<F>(func)
+ );
+ }
+ }
+
+
+//#if 0 && defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
+// template <typename R>
+// template<typename RF>
+// BOOST_THREAD_FUTURE<RF>
+// BOOST_THREAD_FUTURE<R>::then(RF(*func)(BOOST_THREAD_FUTURE<R>&))
+// {
+//
+// typedef RF future_type;
+//
+// if (this->future_)
+// {
+// boost::unique_lock<boost::mutex> lock(this->future_->mutex);
+// detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, RF(*)(BOOST_THREAD_FUTURE&) > *ptr =
+// new detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, RF(*)(BOOST_THREAD_FUTURE&)>(*this, func);
+// if (ptr==0)
+// {
+// return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<future_type>());
+// }
+// this->future_->set_continuation_ptr(ptr, lock);
+// return ptr->get_future();
+// } else {
+// // fixme what to do when the future has no associated state?
+// return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<future_type>());
// }
-// template <class F>
-// BOOST_THREAD_FUTURE<typename boost::result_of<F()>::type>
-// async(F const& f)
+//
+// }
+// template <typename R>
+// template<typename RF>
+// BOOST_THREAD_FUTURE<RF>
+// BOOST_THREAD_FUTURE<R>::then(launch policy, RF(*func)(BOOST_THREAD_FUTURE<R>&))
+// {
+//
+// typedef RF future_type;
+//
+// if (this->future_)
// {
-// return async(launch::any, f);
+// boost::unique_lock<boost::mutex> lock(this->future_->mutex);
+// detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, RF(*)(BOOST_THREAD_FUTURE&) > *ptr =
+// new detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, RF(*)(BOOST_THREAD_FUTURE&)>(*this, func, policy);
+// if (ptr==0)
+// {
+// return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<future_type>());
+// }
+// this->future_->set_continuation_ptr(ptr, lock);
+// return ptr->get_future();
+// } else {
+// // fixme what to do when the future has no associated state?
+// return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<future_type>());
// }
+//
+// }
+//#endif
+
+ 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)
+ {
+ 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_future_async_continuation_shared_state<shared_future<R>, future_type, F>(
+ 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<shared_future<R>, future_type, F>(
+ lock, boost::move(*this), boost::forward<F>(func)
+ )));
+ } else {
+ return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<shared_future<R>, future_type, F>(
+ lock, boost::move(*this), boost::forward<F>(func)
+ )));
+ }
+ }
+
+ 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) {
+ 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>(this->launch_policy(lock)) & int(launch::async)) {
+ return boost::detail::make_future_async_continuation_shared_state<shared_future<R>, future_type, F>(
+ lock, boost::move(*this), boost::forward<F>(func));
+ } else if (underlying_cast<int>(this->launch_policy(lock)) & int(launch::deferred)) {
+ this->future_->wait_internal(lock);
+ return boost::detail::make_future_deferred_continuation_shared_state<shared_future<R>, future_type, F>(
+ lock, boost::move(*this), boost::forward<F>(func));
+ } else {
+ return boost::detail::make_future_async_continuation_shared_state<shared_future<R>, future_type, F>(
+ lock, boost::move(*this), boost::forward<F>(func));
+ }
+ }
+
+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) {
+ 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 parent;
+ public:
+ explicit future_unwrap_shared_state(BOOST_THREAD_RV_REF(F) f)
+ : parent(boost::move(f)) {}
+ virtual void wait(bool ) { // todo see if rethrow must be used
+ boost::unique_lock<boost::mutex> lock(mutex);
+ parent.get().wait();
+ }
+ virtual Rp get() {
+ boost::unique_lock<boost::mutex> lock(mutex);
+ return parent.get().get();
+ }
+ };
+
+ 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->parent.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 <class F>
- BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type()>::type>
- async(launch policy, BOOST_THREAD_FWD_REF(F) f)
+ template <typename R2>
+ BOOST_THREAD_FUTURE<R2>
+ BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >::unwrap()
+ {
+ BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
+ boost::unique_lock<boost::mutex> lock(this->future_->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;
+ csbl::vector<F> vec_;
+
+ static void run(future_when_all_vector_shared_state* that) {
+ try {
+ boost::wait_for_all(that->vec_.begin(), that->vec_.end());
+ that->mark_finished_with_result(boost::move(that->vec_));
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ } catch(thread_interrupted& ) {
+ that->mark_interrupted_finish();
+#endif
+ } catch(...) {
+ that->mark_exceptional_finish();
+ }
+ }
+ void init() {
+ this->thr_ = thread(&future_when_all_vector_shared_state::run, this);
+ }
+
+ 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))
{
- typedef typename boost::result_of<typename decay<F>::type()>::type R;
- if (int(policy) & int(launch::async))
- {
- packaged_task<R> pt( boost::forward<F>(f) );
+ init();
+ }
- BOOST_THREAD_FUTURE<R> ret = pt.get_future();
- boost::thread( boost::move(pt) ).detach();
- return ::boost::move(ret);
- }
- else if (int(policy) & int(launch::deferred))
- {
- packaged_task<R> pt( boost::forward<F>(f) );
+ future_when_all_vector_shared_state(vector_tag, BOOST_THREAD_RV_REF(csbl::vector<F>) v)
+ : vec_(boost::move(v))
+ {
+ init();
+ }
- BOOST_THREAD_FUTURE<R> ret = pt.get_future();
- return ::boost::move(ret);
- } else {
- BOOST_THREAD_FUTURE<R> ret;
- return ::boost::move(ret);
- }
+#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template< typename T0, typename ...T>
+ future_when_all_vector_shared_state(values_tag, BOOST_THREAD_RV_REF(T0) f, BOOST_THREAD_RV_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
+ init();
+ }
+#else
+#endif
+ ~future_when_all_vector_shared_state() {
+ this->join();
+ }
+
+ };
+
+ ////////////////////////////////
+ // 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;
+ csbl::vector<F> vec_;
+
+ static void run(future_when_any_vector_shared_state* that)
+ {
+ try {
+ boost::wait_for_any(that->vec_.begin(), that->vec_.end());
+ that->mark_finished_with_result(boost::move(that->vec_));
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ } catch(thread_interrupted& ) {
+ that->mark_interrupted_finish();
+#endif
+ } catch(...) {
+ that->mark_exceptional_finish();
+ }
+ }
+ void init() {
+ this->thr_ = thread(&future_when_any_vector_shared_state::run, this);
+ }
+
+ 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))
+ {
+ init();
}
- template <class F>
- BOOST_THREAD_FUTURE<typename boost::result_of<F()>::type>
- async(BOOST_THREAD_FWD_REF(F) f)
+
+ future_when_any_vector_shared_state(vector_tag, BOOST_THREAD_RV_REF(csbl::vector<F>) v)
+ : vec_(boost::move(v))
{
- return async(launch::any, boost::forward<F>(f));
+ init();
}
+#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template< typename T0, typename ...T>
+ future_when_any_vector_shared_state(values_tag,
+ BOOST_THREAD_RV_REF(T0) f, BOOST_THREAD_RV_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
+ init();
+ }
#endif
+ ~future_when_any_vector_shared_state() {
+ this->join();
+ }
+
+ };
+
+#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+//#if ! defined(BOOST_NO_CXX11_HDR_TUPLE)
+ template< typename T0, typename ...T>
+ struct future_when_all_tuple_shared_state: future_async_shared_state_base<
+ csbl::tuple<BOOST_THREAD_FUTURE<typename T0::value_type>, BOOST_THREAD_FUTURE<typename T::value_type>... >
+ >
+ {
+
+ };
+ template< typename T0, typename ...T>
+ struct future_when_any_tuple_shared_state: future_async_shared_state_base<
+ csbl::tuple<BOOST_THREAD_FUTURE<typename T0::value_type>, BOOST_THREAD_FUTURE<typename T::value_type>... >
+ >
+ {
+ };
+//#endif
+#endif
+
+#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template< typename ...T>
+ struct are_same : true_type {};
+ template< typename T0 >
+ struct are_same<T0> : true_type {};
+ template< typename T0, typename T1, typename ...T>
+ struct are_same<T0, T1, T...> : integral_constant<bool, is_same<T0,T1>::value && are_same<T1, T...>::value> {};
+
+ template< bool AreSame, typename T0, typename ...T>
+ struct when_type_impl;
+
+ template< typename T0, typename ...T>
+ struct when_type_impl<true, T0, T...>
+ {
+ typedef csbl::vector<typename decay<T0>::type> container_type;
+ typedef typename container_type::value_type value_type;
+ typedef detail::future_when_all_vector_shared_state<value_type> factory_all_type;
+ typedef detail::future_when_any_vector_shared_state<value_type> factory_any_type;
+ };
+//#if ! defined(BOOST_NO_CXX11_HDR_TUPLE)
+ template< typename T0, typename ...T>
+ struct when_type_impl<false, T0, T...>
+ {
+ typedef csbl::tuple<BOOST_THREAD_FUTURE<typename T0::value_type>, BOOST_THREAD_FUTURE<typename T::value_type>... > container_type;
+ typedef detail::future_when_all_tuple_shared_state<T0, T...> factory_all_type;
+ typedef detail::future_when_any_tuple_shared_state<T0, T...> factory_any_type;
+ };
+//#endif
+
+ template< typename T0, typename ...T>
+ struct when_type : when_type_impl<are_same<T0, T...>::value, T0, T...> {};
+#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));
+ return BOOST_THREAD_FUTURE<container_type>(h);
+ }
+
+//#if ! defined(BOOST_NO_CXX11_HDR_TUPLE)
+ inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_all() {
+ return make_ready_future(csbl::tuple<>());
+ }
+//#endif
+
+#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template< typename T0, typename ...T>
+ BOOST_THREAD_FUTURE<typename detail::when_type<T0, T...>::container_type>
+ when_all(BOOST_THREAD_RV_REF(T0) f, BOOST_THREAD_RV_REF(T) ... futures) {
+ typedef typename detail::when_type<T0, T...>::container_type container_type;
+ typedef typename detail::when_type<T0, T...>::factory_all_type factory_type;
+
+ shared_ptr<factory_type>
+ h(new factory_type(detail::values_tag_value, boost::forward<T0>(f), boost::forward<T>(futures)...));
+ 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));
+ return BOOST_THREAD_FUTURE<container_type>(h);
+ }
+
+//#if ! defined(BOOST_NO_CXX11_HDR_TUPLE)
+ inline BOOST_THREAD_FUTURE<csbl::tuple<> > when_any() {
+ return make_ready_future(csbl::tuple<>());
+ }
+//#endif
+
+#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template< typename T0, typename ...T>
+ BOOST_THREAD_FUTURE<typename detail::when_type<T0, T...>::container_type>
+ when_any(BOOST_THREAD_RV_REF(T0) f, BOOST_THREAD_RV_REF(T) ... futures) {
+ typedef typename detail::when_type<T0, T...>::container_type container_type;
+ typedef typename detail::when_type<T0, T...>::factory_any_type factory_type;
+
+ shared_ptr<factory_type>
+ h(new factory_type(detail::values_tag_value, boost::forward<T0>(f), boost::forward<T>(futures)...));
+ return BOOST_THREAD_FUTURE<container_type>(h);
+ }
+#endif
+#endif // BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
}
#endif // BOOST_NO_EXCEPTION
diff --git a/3rdParty/Boost/src/boost/thread/future_error_code.hpp b/3rdParty/Boost/src/boost/thread/future_error_code.hpp
new file mode 100644
index 0000000..6fe9554
--- /dev/null
+++ b/3rdParty/Boost/src/boost/thread/future_error_code.hpp
@@ -0,0 +1,61 @@
+// (C) Copyright 2008-10 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_FUTURE_ERROR_CODE_HPP
+#define BOOST_THREAD_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/3rdParty/Boost/src/boost/thread/is_locked_by_this_thread.hpp b/3rdParty/Boost/src/boost/thread/is_locked_by_this_thread.hpp
new file mode 100644
index 0000000..6344c0f
--- /dev/null
+++ b/3rdParty/Boost/src/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/3rdParty/Boost/src/boost/thread/lock_algorithms.hpp b/3rdParty/Boost/src/boost/thread/lock_algorithms.hpp
new file mode 100644
index 0000000..7a55f92
--- /dev/null
+++ b/3rdParty/Boost/src/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/3rdParty/Boost/src/boost/thread/lock_guard.hpp b/3rdParty/Boost/src/boost/thread/lock_guard.hpp
new file mode 100644
index 0000000..4c2908a
--- /dev/null
+++ b/3rdParty/Boost/src/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/3rdParty/Boost/src/boost/thread/lock_options.hpp b/3rdParty/Boost/src/boost/thread/lock_options.hpp
new file mode 100644
index 0000000..68899ca
--- /dev/null
+++ b/3rdParty/Boost/src/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/3rdParty/Boost/src/boost/thread/lock_types.hpp b/3rdParty/Boost/src/boost/thread/lock_types.hpp
new file mode 100644
index 0000000..2b73edf
--- /dev/null
+++ b/3rdParty/Boost/src/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/3rdParty/Boost/src/boost/thread/lockable_traits.hpp b/3rdParty/Boost/src/boost/thread/lockable_traits.hpp
new file mode 100644
index 0000000..8a17ae7
--- /dev/null
+++ b/3rdParty/Boost/src/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/3rdParty/Boost/src/boost/thread/locks.hpp b/3rdParty/Boost/src/boost/thread/locks.hpp
index c11c2bd..6749964 100644
--- a/3rdParty/Boost/src/boost/thread/locks.hpp
+++ b/3rdParty/Boost/src/boost/thread/locks.hpp
@@ -6,1822 +6,11 @@
#ifndef BOOST_THREAD_LOCKS_HPP
#define BOOST_THREAD_LOCKS_HPP
-#include <boost/thread/detail/config.hpp>
-#include <boost/thread/exceptions.hpp>
-#include <boost/thread/detail/move.hpp>
-#include <algorithm>
-#include <iterator>
-#include <boost/thread/thread_time.hpp>
-#include <boost/detail/workaround.hpp>
-#include <boost/type_traits/is_class.hpp>
-#ifdef BOOST_THREAD_USES_CHRONO
-#include <boost/chrono/time_point.hpp>
-#include <boost/chrono/duration.hpp>
-#endif
-
-#include <boost/config/abi_prefix.hpp>
-
-namespace boost
-{
- struct xtime;
-
-#if defined(BOOST_NO_SFINAE) || \
- BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) || \
- BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
-#define BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
-#endif
-
-#ifndef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
- namespace detail
- {
-#define BOOST_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_DEFINE_HAS_MEMBER_CALLED(lock);
- BOOST_DEFINE_HAS_MEMBER_CALLED(unlock);
- BOOST_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_mutex_type
- {
- BOOST_STATIC_CONSTANT(bool, value = detail::has_member_lock<T>::value &&
- detail::has_member_unlock<T>::value &&
- detail::has_member_try_lock<T>::value);
-
- };
-#else
- template<typename T>
- struct is_mutex_type
- {
- BOOST_STATIC_CONSTANT(bool, value = false);
- };
-#endif
-
- 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={};
-
- 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
- template<typename T>
- struct is_mutex_type<unique_lock<T> >
- {
- BOOST_STATIC_CONSTANT(bool, value = true);
- };
-
- template<typename T>
- struct is_mutex_type<shared_lock<T> >
- {
- BOOST_STATIC_CONSTANT(bool, value = true);
- };
-
- template<typename T>
- struct is_mutex_type<upgrade_lock<T> >
- {
- BOOST_STATIC_CONSTANT(bool, value = true);
- };
-
- template<typename T>
- struct is_mutex_type<detail::try_lock_wrapper<T> >
- {
- BOOST_STATIC_CONSTANT(bool, value = true);
- };
-
- class mutex;
- class timed_mutex;
- class recursive_mutex;
- class recursive_timed_mutex;
- class shared_mutex;
-
- template<>
- struct is_mutex_type<mutex>
- {
- BOOST_STATIC_CONSTANT(bool, value = true);
- };
- template<>
- struct is_mutex_type<timed_mutex>
- {
- BOOST_STATIC_CONSTANT(bool, value = true);
- };
- template<>
- struct is_mutex_type<recursive_mutex>
- {
- BOOST_STATIC_CONSTANT(bool, value = true);
- };
- template<>
- struct is_mutex_type<recursive_timed_mutex>
- {
- BOOST_STATIC_CONSTANT(bool, value = true);
- };
- template<>
- struct is_mutex_type<shared_mutex>
- {
- BOOST_STATIC_CONSTANT(bool, value = true);
- };
-
-#endif
-
- 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_)
- {}
- ~lock_guard()
- {
- m.unlock();
- }
- };
-
- 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)
- {}
- 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();
- }
- 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);
- }
-
-#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
- 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
-
- 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(system::errc::operation_not_permitted, "boost unique_lock has no mutex"));
- }
- if(owns_lock())
- {
- boost::throw_exception(boost::lock_error(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(system::errc::operation_not_permitted, "boost unique_lock has no mutex"));
- }
- if(owns_lock())
- {
- boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost unique_lock owns already the mutex"));
- }
- is_locked=m->try_lock();
- return is_locked;
- }
- template<typename TimeDuration>
- bool timed_lock(TimeDuration const& relative_time)
- {
- if(m==0)
- {
- boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost unique_lock has no mutex"));
- }
- if(owns_lock())
- {
- boost::throw_exception(boost::lock_error(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(system::errc::operation_not_permitted, "boost unique_lock has no mutex"));
- }
- if(owns_lock())
- {
- boost::throw_exception(boost::lock_error(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(system::errc::operation_not_permitted, "boost unique_lock has no mutex"));
- }
- if(owns_lock())
- {
- boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost unique_lock owns already the mutex"));
- }
- is_locked=m->timed_lock(absolute_time);
- return is_locked;
- }
-
-#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(system::errc::operation_not_permitted, "boost unique_lock has no mutex"));
- }
- if(owns_lock())
- {
- boost::throw_exception(boost::lock_error(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(system::errc::operation_not_permitted, "boost unique_lock has no mutex"));
- }
- if(owns_lock())
- {
- boost::throw_exception(boost::lock_error(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(system::errc::operation_not_permitted, "boost unique_lock has no mutex"));
- }
- if(!owns_lock())
- {
- boost::throw_exception(boost::lock_error(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)
- {}
- 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();
- }
- shared_lock(Mutex& m_,system_time const& target_time):
- m(&m_),is_locked(false)
- {
- timed_lock(target_time);
- }
-
-#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;
- }
-
-
- 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(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
- }
- if(owns_lock())
- {
- boost::throw_exception(boost::lock_error(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(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
- }
- if(owns_lock())
- {
- boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost shared_lock owns already the mutex"));
- }
- is_locked=m->try_lock_shared();
- return is_locked;
- }
- bool timed_lock(boost::system_time const& target_time)
- {
- if(m==0)
- {
- boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
- }
- if(owns_lock())
- {
- boost::throw_exception(boost::lock_error(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(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
- }
- if(owns_lock())
- {
- boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost shared_lock owns already the mutex"));
- }
- is_locked=m->timed_lock_shared(target_time);
- return is_locked;
- }
-#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(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
- }
- if(owns_lock())
- {
- boost::throw_exception(boost::lock_error(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(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
- }
- if(owns_lock())
- {
- boost::throw_exception(boost::lock_error(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(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
- }
- if(!owns_lock())
- {
- boost::throw_exception(boost::lock_error(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)
- {}
- 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;
- }
-
- 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(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
- }
- if(owns_lock())
- {
- boost::throw_exception(boost::lock_error(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(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
- }
- if(owns_lock())
- {
- boost::throw_exception(boost::lock_error(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(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
- }
- if(!owns_lock())
- {
- boost::throw_exception(boost::lock_error(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(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
- }
- if(owns_lock())
- {
- boost::throw_exception(boost::lock_error(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(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
- }
- if(owns_lock())
- {
- boost::throw_exception(boost::lock_error(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;
- }
-
- 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();
- }
- };
-
- 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)
- {}
- 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
- {
- 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);
- }
-
- 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>
+#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/3rdParty/Boost/src/boost/thread/mutex.hpp b/3rdParty/Boost/src/boost/thread/mutex.hpp
index 4669886..05c6094 100644
--- a/3rdParty/Boost/src/boost/thread/mutex.hpp
+++ b/3rdParty/Boost/src/boost/thread/mutex.hpp
@@ -3,7 +3,7 @@
// mutex.hpp
//
-// (C) Copyright 2007 Anthony Williams
+// (C) Copyright 2007 Anthony Williams
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -18,4 +18,36 @@
#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/3rdParty/Boost/src/boost/thread/once.hpp b/3rdParty/Boost/src/boost/thread/once.hpp
index acd216e..9fcfb53 100644
--- a/3rdParty/Boost/src/boost/thread/once.hpp
+++ b/3rdParty/Boost/src/boost/thread/once.hpp
@@ -9,11 +9,18 @@
// 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
@@ -24,7 +31,9 @@ namespace boost
{
// template<class Callable, class ...Args> void
// call_once(once_flag& flag, Callable&& func, Args&&... args);
- inline void call_once(void (*func)(),once_flag& flag)
+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);
}
diff --git a/3rdParty/Boost/src/boost/thread/pthread/condition_variable.hpp b/3rdParty/Boost/src/boost/thread/pthread/condition_variable.hpp
index aa71007..b1b76b0 100644
--- a/3rdParty/Boost/src/boost/thread/pthread/condition_variable.hpp
+++ b/3rdParty/Boost/src/boost/thread/pthread/condition_variable.hpp
@@ -4,11 +4,13 @@
// 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 Vicente J. Botet Escriba
+// (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>
@@ -20,10 +22,12 @@
namespace boost
{
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
namespace this_thread
{
void BOOST_THREAD_DECL interruption_point();
}
+#endif
namespace thread_cv_detail
{
@@ -53,57 +57,88 @@ namespace boost
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);
guard.activate(m);
do {
res = pthread_cond_wait(&cond,&internal_mutex);
} while (res == EINTR);
+#else
+ //boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex);
+ pthread_mutex_t* the_mutex = m.mutex()->native_handle();
+ do {
+ res = pthread_cond_wait(&cond,the_mutex);
+ } while (res == EINTR);
+#endif
}
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
this_thread::interruption_point();
+#endif
if(res)
{
- boost::throw_exception(condition_error(res, "boost:: condition_variable constructor failed in pthread_cond_wait"));
+ boost::throw_exception(condition_error(res, "boost::condition_variable::wait failed in pthread_cond_wait"));
}
}
- inline bool condition_variable::do_timed_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, "condition_variable do_timed_wait: mutex not locked"));
-
+ {
+ boost::throw_exception(condition_error(EPERM, "boost::condition_variable::do_wait_until() failed precondition mutex not owned"));
+ }
+#endif
thread_cv_detail::lock_on_exit<unique_lock<mutex> > guard;
int cond_res;
{
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
guard.activate(m);
cond_res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout);
+#else
+ //boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex);
+ pthread_mutex_t* the_mutex = m.mutex()->native_handle();
+ cond_res=pthread_cond_timedwait(&cond,the_mutex,&timeout);
+#endif
}
+#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, "condition_variable failed in pthread_cond_timedwait"));
+ 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));
}
@@ -119,13 +154,13 @@ namespace boost
int const res=pthread_mutex_init(&internal_mutex,NULL);
if(res)
{
- boost::throw_exception(thread_resource_error(res, "condition_variable_any failed in pthread_mutex_init"));
+ boost::throw_exception(thread_resource_error(res, "boost::condition_variable_any::condition_variable_any() failed in pthread_mutex_init"));
}
int const res2=pthread_cond_init(&cond,NULL);
if(res2)
{
BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
- boost::throw_exception(thread_resource_error(res, "condition_variable_any failed in pthread_cond_init"));
+ boost::throw_exception(thread_resource_error(res, "boost::condition_variable_any::condition_variable_any() failed in pthread_cond_init"));
}
}
~condition_variable_any()
@@ -140,14 +175,20 @@ namespace boost
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, "condition_variable_any failed in pthread_cond_wait"));
+ boost::throw_exception(condition_error(res, "boost::condition_variable_any::wait() failed in pthread_cond_wait"));
}
}
@@ -157,16 +198,17 @@ namespace boost
while(!pred()) wait(m);
}
+#if defined BOOST_THREAD_USES_DATETIME
template<typename lock_type>
- bool timed_wait(lock_type& m,boost::system_time const& wait_until)
+ bool timed_wait(lock_type& m,boost::system_time const& abs_time)
{
- struct timespec const timeout=detail::get_timespec(wait_until);
- return do_timed_wait(m, timeout);
+ 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& wait_until)
+ bool timed_wait(lock_type& m,xtime const& abs_time)
{
- return timed_wait(m,system_time(wait_until));
+ return timed_wait(m,system_time(abs_time));
}
template<typename lock_type,typename duration_type>
@@ -176,20 +218,20 @@ namespace boost
}
template<typename lock_type,typename predicate_type>
- bool timed_wait(lock_type& m,boost::system_time const& wait_until,predicate_type pred)
+ bool timed_wait(lock_type& m,boost::system_time const& abs_time, predicate_type pred)
{
while (!pred())
{
- if(!timed_wait(m, wait_until))
+ 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& wait_until,predicate_type pred)
+ bool timed_wait(lock_type& m,xtime const& abs_time, predicate_type pred)
{
- return timed_wait(m,system_time(wait_until),pred);
+ return timed_wait(m,system_time(abs_time),pred);
}
template<typename lock_type,typename duration_type,typename predicate_type>
@@ -197,7 +239,7 @@ namespace boost
{
return timed_wait(m,get_system_time()+wait_duration,pred);
}
-
+#endif
#ifdef BOOST_THREAD_USES_CHRONO
template <class lock_type,class Duration>
cv_status
@@ -265,26 +307,26 @@ namespace boost
const chrono::duration<Rep, Period>& d,
Predicate pred)
{
- while (!pred())
- {
- if (wait_for(lock, d) == cv_status::timeout)
- return pred();
- }
- return true;
+ return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred));
+
+// while (!pred())
+// {
+// if (wait_for(lock, d) == cv_status::timeout)
+// return pred();
+// }
+// return true;
}
template <class lock_type>
- inline void wait_until(
+ 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;
- seconds s = duration_cast<seconds>(d);
- ts.tv_sec = static_cast<long>(s.count());
- ts.tv_nsec = static_cast<long>((d - s).count());
- do_timed_wait(lk, ts);
+ timespec ts = boost::detail::to_timespec(d);
+ if (do_wait_until(lk, ts)) return cv_status::no_timeout;
+ else return cv_status::timeout;
}
#endif
@@ -302,25 +344,31 @@ namespace boost
private: // used by boost::thread::try_join_until
template <class lock_type>
- inline bool do_timed_wait(
+ 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, "condition_variable_any failed in pthread_cond_timedwait"));
+ boost::throw_exception(condition_error(res, "boost::condition_variable_any::do_wait_until() failed in pthread_cond_timedwait"));
}
return true;
}
diff --git a/3rdParty/Boost/src/boost/thread/pthread/condition_variable_fwd.hpp b/3rdParty/Boost/src/boost/thread/pthread/condition_variable_fwd.hpp
index dbb3892..e18030f 100644
--- a/3rdParty/Boost/src/boost/thread/pthread/condition_variable_fwd.hpp
+++ b/3rdParty/Boost/src/boost/thread/pthread/condition_variable_fwd.hpp
@@ -4,22 +4,26 @@
// 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 Vicente J. Botet Escriba
+// (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/locks.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
@@ -28,33 +32,58 @@ namespace boost
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 const res=pthread_mutex_init(&internal_mutex,NULL);
if(res)
{
- boost::throw_exception(thread_resource_error(res, "boost:: condition_variable constructor failed in pthread_mutex_init"));
+ boost::throw_exception(thread_resource_error(res, "boost::condition_variable::condition_variable() constructor failed in pthread_mutex_init"));
}
+#endif
int const res2=pthread_cond_init(&cond,NULL);
if(res2)
{
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
- boost::throw_exception(thread_resource_error(res2, "boost:: condition_variable constructor failed in pthread_cond_init"));
+#endif
+ boost::throw_exception(thread_resource_error(res2, "boost::condition_variable::condition_variable() constructor failed in pthread_cond_init"));
}
}
~condition_variable()
{
- BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
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_VERIFY(!ret);
+ BOOST_ASSERT(!ret);
}
void wait(unique_lock<mutex>& m);
@@ -66,23 +95,24 @@ namespace boost
}
+#if defined BOOST_THREAD_USES_DATETIME
inline bool timed_wait(
unique_lock<mutex>& m,
- boost::system_time const& wait_until)
+ boost::system_time const& abs_time)
{
#if defined BOOST_THREAD_WAIT_BUG
- struct timespec const timeout=detail::get_timespec(wait_until + BOOST_THREAD_WAIT_BUG);
- return do_timed_wait(m, timeout);
+ 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::get_timespec(wait_until);
- return do_timed_wait(m, timeout);
+ 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& wait_until)
+ xtime const& abs_time)
{
- return timed_wait(m,system_time(wait_until));
+ return timed_wait(m,system_time(abs_time));
}
template<typename duration_type>
@@ -96,11 +126,11 @@ namespace boost
template<typename predicate_type>
bool timed_wait(
unique_lock<mutex>& m,
- boost::system_time const& wait_until,predicate_type pred)
+ boost::system_time const& abs_time,predicate_type pred)
{
while (!pred())
{
- if(!timed_wait(m, wait_until))
+ if(!timed_wait(m, abs_time))
return pred();
}
return true;
@@ -109,9 +139,9 @@ namespace boost
template<typename predicate_type>
bool timed_wait(
unique_lock<mutex>& m,
- xtime const& wait_until,predicate_type pred)
+ xtime const& abs_time,predicate_type pred)
{
- return timed_wait(m,system_time(wait_until),pred);
+ return timed_wait(m,system_time(abs_time),pred);
}
template<typename duration_type,typename predicate_type>
@@ -121,6 +151,7 @@ namespace boost
{
return timed_wait(m,get_system_time()+wait_duration,pred);
}
+#endif
#ifdef BOOST_THREAD_USES_CHRONO
@@ -190,12 +221,14 @@ namespace boost
const chrono::duration<Rep, Period>& d,
Predicate pred)
{
- while (!pred())
- {
- if (wait_for(lock, d) == cv_status::timeout)
- return pred();
- }
- return true;
+ return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred));
+
+// while (!pred())
+// {
+// if (wait_for(lock, d) == cv_status::timeout)
+// return pred();
+// }
+// return true;
}
#endif
@@ -210,27 +243,21 @@ namespace boost
void notify_all() BOOST_NOEXCEPT;
#ifdef BOOST_THREAD_USES_CHRONO
- inline void wait_until(
+ 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;
- seconds s = duration_cast<seconds>(d);
- ts.tv_sec = static_cast<long>(s.count());
- ts.tv_nsec = static_cast<long>((d - s).count());
- do_timed_wait(lk, ts);
+ timespec ts = boost::detail::to_timespec(d);
+ if (do_wait_until(lk, ts)) return cv_status::no_timeout;
+ else return cv_status::timeout;
}
#endif
- //private: // used by boost::thread::try_join_until
-
- inline bool do_timed_wait(
- unique_lock<mutex>& lock,
- struct timespec const &timeout);
};
BOOST_THREAD_DECL void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
+
}
diff --git a/3rdParty/Boost/src/boost/thread/pthread/mutex.hpp b/3rdParty/Boost/src/boost/thread/pthread/mutex.hpp
index 2c5af92..3e9af2a 100644
--- a/3rdParty/Boost/src/boost/thread/pthread/mutex.hpp
+++ b/3rdParty/Boost/src/boost/thread/pthread/mutex.hpp
@@ -6,10 +6,14 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/thread/detail/config.hpp>
#include <pthread.h>
#include <boost/throw_exception.hpp>
+#include <boost/core/ignore_unused.hpp>
#include <boost/thread/exceptions.hpp>
-#include <boost/thread/locks.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>
@@ -23,15 +27,68 @@
#include <boost/thread/detail/delete.hpp>
#ifdef _POSIX_TIMEOUTS
-#if _POSIX_TIMEOUTS >= 0 && _POSIX_C_SOURCE>=200112L
+#if _POSIX_TIMEOUTS >= 0 && _POSIX_TIMEOUTS>=200112L
+#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
#define BOOST_PTHREAD_HAS_TIMEDLOCK
#endif
#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:
@@ -49,20 +106,14 @@ namespace boost
}
~mutex()
{
- int ret;
- do
- {
- ret = pthread_mutex_destroy(&m);
- } while (ret == EINTR);
+ int const res = posix::pthread_mutex_destroy(&m);
+ boost::ignore_unused(res);
+ BOOST_ASSERT(!res);
}
void lock()
{
- int res;
- do
- {
- res = pthread_mutex_lock(&m);
- } while (res == EINTR);
+ int res = posix::pthread_mutex_lock(&m);
if (res)
{
boost::throw_exception(lock_error(res,"boost: mutex lock failed in pthread_mutex_lock"));
@@ -71,12 +122,11 @@ namespace boost
void unlock()
{
- int ret;
- do
+ int res = posix::pthread_mutex_unlock(&m);
+ if (res)
{
- ret = pthread_mutex_unlock(&m);
- } while (ret == EINTR);
- BOOST_VERIFY(!ret);
+ boost::throw_exception(lock_error(res,"boost: mutex unlock failed in pthread_mutex_unlock"));
+ }
}
bool try_lock()
@@ -86,12 +136,8 @@ namespace boost
{
res = pthread_mutex_trylock(&m);
} while (res == EINTR);
- if(res && (res!=EBUSY))
+ if (res==EBUSY)
{
- // The following throw_exception has been replaced by an assertion and just return false,
- // as this is an internal error and the user can do nothing with the exception.
- //boost::throw_exception(lock_error(res,"boost: mutex try_lock failed in pthread_mutex_trylock"));
- BOOST_ASSERT_MSG(false ,"boost: mutex try_lock failed in pthread_mutex_trylock");
return false;
}
@@ -105,8 +151,10 @@ namespace boost
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;
@@ -132,7 +180,8 @@ namespace boost
int const res2=pthread_cond_init(&cond,NULL);
if(res2)
{
- BOOST_VERIFY(!pthread_mutex_destroy(&m));
+ 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;
@@ -140,12 +189,13 @@ namespace boost
}
~timed_mutex()
{
- BOOST_VERIFY(!pthread_mutex_destroy(&m));
+ 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)
{
@@ -155,23 +205,39 @@ namespace boost
{
return timed_lock(system_time(absolute_time));
}
-
+#endif
#ifdef BOOST_PTHREAD_HAS_TIMEDLOCK
void lock()
{
- BOOST_VERIFY(!pthread_mutex_lock(&m));
+ 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()
{
- BOOST_VERIFY(!pthread_mutex_unlock(&m));
+ int res = posix::pthread_mutex_unlock(&m);
+ if (res)
+ {
+ boost::throw_exception(lock_error(res,"boost: mutex unlock failed in pthread_mutex_unlock"));
+ }
}
bool try_lock()
{
- int const res=pthread_mutex_trylock(&m);
- BOOST_ASSERT(!res || res==EBUSY);
- return !res;
+ int res;
+ do
+ {
+ res = pthread_mutex_trylock(&m);
+ } while (res == EINTR);
+ if (res==EBUSY)
+ {
+ return false;
+ }
+
+ return !res;
}
@@ -232,12 +298,13 @@ namespace boost
public:
#endif
+#if defined BOOST_THREAD_USES_DATETIME
bool timed_lock(system_time const & abs_time)
{
- struct timespec const ts=detail::get_timespec(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)
@@ -261,12 +328,9 @@ namespace boost
}
bool try_lock_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp)
{
- using namespace chrono;
- nanoseconds d = tp.time_since_epoch();
- timespec ts;
- seconds s = duration_cast<seconds>(d);
- ts.tv_sec = static_cast<long>(s.count());
- ts.tv_nsec = static_cast<long>((d - s).count());
+ //using namespace chrono;
+ chrono::nanoseconds d = tp.time_since_epoch();
+ timespec ts = boost::detail::to_timespec(d);
return do_try_lock_until(ts);
}
#endif
@@ -278,9 +342,11 @@ namespace boost
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
};
}
diff --git a/3rdParty/Boost/src/boost/thread/pthread/once.hpp b/3rdParty/Boost/src/boost/thread/pthread/once.hpp
index 02c2732..0bef038 100644
--- a/3rdParty/Boost/src/boost/thread/pthread/once.hpp
+++ b/3rdParty/Boost/src/boost/thread/pthread/once.hpp
@@ -11,11 +11,14 @@
// 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/detail/no_exceptions_support.hpp>
+#include <boost/core/no_exceptions_support.hpp>
+#include <boost/bind.hpp>
#include <boost/assert.hpp>
#include <boost/config/abi_prefix.hpp>
@@ -26,21 +29,32 @@
namespace boost
{
-#define BOOST_ONCE_INITIAL_FLAG_VALUE 0
+ struct once_flag;
+
+ #define BOOST_ONCE_INITIAL_FLAG_VALUE 0
namespace thread_detail
{
-//#ifdef SIG_ATOMIC_MAX
-// typedef sig_atomic_t uintmax_atomic_t;
-// #define BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_MAX_C SIG_ATOMIC_MAX
-//#else
- typedef unsigned long uintmax_atomic_t;
- #define BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_C2(value) value##ul
+ 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)
-//#endif
+
}
#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
{
@@ -50,11 +64,26 @@ namespace boost
{}
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);
+ 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
@@ -65,59 +94,445 @@ namespace boost
#define BOOST_ONCE_INIT {BOOST_ONCE_INITIAL_FLAG_VALUE}
#endif // BOOST_THREAD_PROVIDES_ONCE_CXX11
- namespace detail
+
+#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 thread_detail::uintmax_atomic_t& get_once_per_thread_epoch();
- BOOST_THREAD_DECL extern thread_detail::uintmax_atomic_t once_global_epoch;
+ 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
- template<typename Function>
- void call_once(once_flag& flag,Function f)
+
+
+#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)
{
- 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=detail::get_once_per_thread_epoch();
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
- if(epoch<this_thread_epoch)
+ while(flag.epoch<=being_initialized)
{
- pthread::pthread_mutex_scoped_lock lk(&detail::once_epoch_mutex);
+ 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();
- while(flag.epoch<=being_initialized)
+ 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)
{
- if(flag.epoch==uninitialized_flag)
+ flag.epoch=being_initialized;
+ BOOST_TRY
{
- flag.epoch=being_initialized;
- BOOST_TRY
- {
- pthread::pthread_mutex_scoped_unlock relocker(&detail::once_epoch_mutex);
- f();
- }
- BOOST_CATCH (...)
- {
- flag.epoch=uninitialized_flag;
- BOOST_VERIFY(!pthread_cond_broadcast(&detail::once_epoch_cv));
- BOOST_RETHROW
- }
- BOOST_CATCH_END
- flag.epoch=--detail::once_global_epoch;
- BOOST_VERIFY(!pthread_cond_broadcast(&detail::once_epoch_cv));
+ 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;
}
- else
+ BOOST_CATCH (...)
{
- while(flag.epoch==being_initialized)
- {
- BOOST_VERIFY(!pthread_cond_wait(&detail::once_epoch_cv,&detail::once_epoch_mutex));
- }
+ 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=detail::once_global_epoch;
}
+ this_thread_epoch=thread_detail::once_global_epoch;
}
+ }
+
+#endif
+
}
#include <boost/config/abi_suffix.hpp>
diff --git a/3rdParty/Boost/src/boost/thread/pthread/once_atomic.hpp b/3rdParty/Boost/src/boost/thread/pthread/once_atomic.hpp
new file mode 100644
index 0000000..923f07b
--- /dev/null
+++ b/3rdParty/Boost/src/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);
+ }
+ }
+
+ 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
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
+
diff --git a/3rdParty/Boost/src/boost/thread/pthread/recursive_mutex.hpp b/3rdParty/Boost/src/boost/thread/pthread/recursive_mutex.hpp
index 2a6bc7d..9330d77 100644
--- a/3rdParty/Boost/src/boost/thread/pthread/recursive_mutex.hpp
+++ b/3rdParty/Boost/src/boost/thread/pthread/recursive_mutex.hpp
@@ -9,7 +9,9 @@
#include <pthread.h>
#include <boost/throw_exception.hpp>
#include <boost/thread/exceptions.hpp>
-#include <boost/thread/locks.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
@@ -26,10 +28,13 @@
#include <boost/thread/detail/delete.hpp>
#ifdef _POSIX_TIMEOUTS
-#if _POSIX_TIMEOUTS >= 0
+#if _POSIX_TIMEOUTS >= 0 && _POSIX_TIMEOUTS>=200112L
+#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
#define BOOST_PTHREAD_HAS_TIMEDLOCK
#endif
#endif
+#endif
+
#if defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE) && defined(BOOST_PTHREAD_HAS_TIMEDLOCK)
#define BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK
@@ -167,8 +172,10 @@ namespace boost
#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;
@@ -232,11 +239,13 @@ namespace boost
#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()
@@ -334,12 +343,13 @@ namespace boost
#endif
+#if defined BOOST_THREAD_USES_DATETIME
bool timed_lock(system_time const & abs_time)
{
- struct timespec const ts=detail::get_timespec(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)
@@ -363,12 +373,9 @@ namespace boost
}
bool try_lock_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp)
{
- using namespace chrono;
- nanoseconds d = tp.time_since_epoch();
- timespec ts;
- seconds s = duration_cast<seconds>(d);
- ts.tv_sec = static_cast<long>(s.count());
- ts.tv_nsec = static_cast<long>((d - s).count());
+ //using namespace chrono;
+ chrono::nanoseconds d = tp.time_since_epoch();
+ timespec ts = boost::detail::to_timespec(d);
return do_try_lock_until(ts);
}
#endif
@@ -380,9 +387,11 @@ namespace boost
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
};
}
diff --git a/3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp b/3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp
index cf45188..458d6c8 100644
--- a/3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp
+++ b/3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp
@@ -12,12 +12,15 @@
#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>
@@ -26,8 +29,125 @@ namespace boost
class shared_mutex
{
private:
- struct state_data
+ 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;
@@ -49,12 +169,11 @@ namespace boost
}
public:
+
BOOST_THREAD_NO_COPYABLE(shared_mutex)
shared_mutex()
{
- state_data state_={0,0,0,0};
- state=state_;
}
~shared_mutex()
@@ -63,44 +182,45 @@ namespace boost
void lock_shared()
{
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
boost::this_thread::disable_interruption do_not_disturb;
- boost::mutex::scoped_lock lk(state_change);
-
- while(state.exclusive || state.exclusive_waiting_blocked)
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ while(!state.can_lock_shared())
{
shared_cond.wait(lk);
}
- ++state.shared_count;
+ state.lock_shared();
}
bool try_lock_shared()
{
- boost::mutex::scoped_lock lk(state_change);
+ boost::unique_lock<boost::mutex> lk(state_change);
- if(state.exclusive || state.exclusive_waiting_blocked)
+ if(!state.can_lock_shared())
{
return false;
}
- else
- {
- ++state.shared_count;
- return true;
- }
+ 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;
- boost::mutex::scoped_lock lk(state_change);
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
- while(state.exclusive || state.exclusive_waiting_blocked)
+ while(!state.can_lock_shared())
{
if(!shared_cond.timed_wait(lk,timeout))
{
return false;
}
}
- ++state.shared_count;
+ state.lock_shared();
return true;
}
@@ -109,6 +229,7 @@ namespace boost
{
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)
@@ -118,36 +239,43 @@ namespace boost
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;
- boost::mutex::scoped_lock lk(state_change);
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
- while(state.exclusive || state.exclusive_waiting_blocked)
+ 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.shared_count;
+ state.lock_shared();
return true;
}
#endif
void unlock_shared()
{
- boost::mutex::scoped_lock lk(state_change);
- bool const last_reader=!--state.shared_count;
-
- if(last_reader)
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_shared();
+ state.unlock_shared();
+ if (! state.more_shared())
{
- if(state.upgrade)
+ 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();
}
@@ -155,10 +283,12 @@ namespace boost
void lock()
{
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
boost::this_thread::disable_interruption do_not_disturb;
- boost::mutex::scoped_lock lk(state_change);
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
- while(state.shared_count || state.exclusive)
+ while (state.shared_count || state.exclusive)
{
state.exclusive_waiting_blocked=true;
exclusive_cond.wait(lk);
@@ -166,10 +296,13 @@ namespace boost
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;
- boost::mutex::scoped_lock lk(state_change);
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
while(state.shared_count || state.exclusive)
{
@@ -194,7 +327,7 @@ namespace boost
{
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)
@@ -204,8 +337,10 @@ namespace boost
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;
- boost::mutex::scoped_lock lk(state_change);
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
while(state.shared_count || state.exclusive)
{
@@ -228,7 +363,7 @@ namespace boost
bool try_lock()
{
- boost::mutex::scoped_lock lk(state_change);
+ boost::unique_lock<boost::mutex> lk(state_change);
if(state.shared_count || state.exclusive)
{
@@ -244,28 +379,35 @@ namespace boost
void unlock()
{
- boost::mutex::scoped_lock lk(state_change);
+ 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;
- boost::mutex::scoped_lock lk(state_change);
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
{
shared_cond.wait(lk);
}
- ++state.shared_count;
+ 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;
- boost::mutex::scoped_lock lk(state_change);
+#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))
@@ -277,7 +419,7 @@ namespace boost
break;
}
}
- ++state.shared_count;
+ state.lock_shared();
state.upgrade=true;
return true;
}
@@ -287,7 +429,7 @@ namespace boost
{
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)
@@ -297,8 +439,10 @@ namespace boost
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;
- boost::mutex::scoped_lock lk(state_change);
+#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))
@@ -310,68 +454,75 @@ namespace boost
break;
}
}
- ++state.shared_count;
+ state.lock_shared();
state.upgrade=true;
return true;
}
#endif
bool try_lock_upgrade()
{
- boost::mutex::scoped_lock lk(state_change);
+ boost::unique_lock<boost::mutex> lk(state_change);
if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
{
return false;
}
else
{
- ++state.shared_count;
+ state.lock_shared();
state.upgrade=true;
+ state.assert_lock_upgraded();
return true;
}
}
void unlock_upgrade()
{
- boost::mutex::scoped_lock lk(state_change);
- state.upgrade=false;
- bool const last_reader=!--state.shared_count;
-
- if(last_reader)
+ 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();
+ 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;
- boost::mutex::scoped_lock lk(state_change);
- --state.shared_count;
- while(state.shared_count)
+#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::mutex::scoped_lock lk(state_change);
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_locked();
state.exclusive=false;
state.upgrade=true;
- ++state.shared_count;
+ state.lock_shared();
state.exclusive_waiting_blocked=false;
+ state.assert_lock_upgraded();
release_waiters();
}
bool try_unlock_upgrade_and_lock()
{
- boost::mutex::scoped_lock lk(state_change);
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_upgraded();
if( !state.exclusive
&& !state.exclusive_waiting_blocked
&& state.upgrade
@@ -380,6 +531,7 @@ namespace boost
state.shared_count=0;
state.exclusive=true;
state.upgrade=false;
+ state.assert_locked();
return true;
}
return false;
@@ -398,8 +550,11 @@ namespace boost
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;
- boost::mutex::scoped_lock lk(state_change);
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_upgraded();
if (state.shared_count != 1)
{
for (;;)
@@ -422,9 +577,10 @@ namespace boost
// Shared <-> Exclusive
void unlock_and_lock_shared()
{
- boost::mutex::scoped_lock lk(state_change);
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_locked();
state.exclusive=false;
- ++state.shared_count;
+ state.lock_shared();
state.exclusive_waiting_blocked=false;
release_waiters();
}
@@ -432,7 +588,8 @@ namespace boost
#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
bool try_unlock_shared_and_lock()
{
- boost::mutex::scoped_lock lk(state_change);
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_shared();
if( !state.exclusive
&& !state.exclusive_waiting_blocked
&& !state.upgrade
@@ -458,8 +615,11 @@ namespace boost
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;
- boost::mutex::scoped_lock lk(state_change);
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_shared();
if (state.shared_count != 1)
{
for (;;)
@@ -483,7 +643,8 @@ namespace boost
// Shared <-> Upgrade
void unlock_upgrade_and_lock_shared()
{
- boost::mutex::scoped_lock lk(state_change);
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_upgraded();
state.upgrade=false;
state.exclusive_waiting_blocked=false;
release_waiters();
@@ -492,7 +653,8 @@ namespace boost
#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
bool try_unlock_shared_and_lock_upgrade()
{
- boost::mutex::scoped_lock lk(state_change);
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_shared();
if( !state.exclusive
&& !state.exclusive_waiting_blocked
&& !state.upgrade
@@ -517,8 +679,11 @@ namespace boost
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;
- boost::mutex::scoped_lock lk(state_change);
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_shared();
if( state.exclusive
|| state.exclusive_waiting_blocked
|| state.upgrade
diff --git a/3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp b/3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp
index db4e09f..801f470 100644
--- a/3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp
+++ b/3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp
@@ -8,13 +8,13 @@
#include <boost/thread/detail/config.hpp>
#include <boost/thread/exceptions.hpp>
-#include <boost/thread/locks.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/optional.hpp>
#include <boost/assert.hpp>
#ifdef BOOST_THREAD_USES_CHRONO
#include <boost/chrono/system_clocks.hpp>
@@ -24,6 +24,10 @@
#include <vector>
#include <utility>
+#if defined(__ANDROID__)
+#include <asm/page.h> // http://code.google.com/p/android/issues/detail?id=39983
+#endif
+
#include <pthread.h>
#include <unistd.h>
@@ -77,6 +81,7 @@ namespace boost
namespace detail
{
+ struct shared_state_base;
struct tss_cleanup_function;
struct thread_exit_callback_node;
struct tss_data_node
@@ -107,8 +112,7 @@ namespace boost
bool joined;
boost::detail::thread_exit_callback_node* thread_exit_callbacks;
std::map<void const*,boost::detail::tss_data_node> tss_data;
- bool interrupt_enabled;
- bool interrupt_requested;
+
pthread_mutex_t* cond_mutex;
pthread_cond_t* current_cond;
typedef std::vector<std::pair<condition_variable*, mutex*>
@@ -116,27 +120,49 @@ namespace boost
> 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),
- interrupt_enabled(true),
- interrupt_requested(false),
+ cond_mutex(0),
current_cond(0),
- notify()
+ 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;
- void notify_all_at_thread_exit(condition_variable* cv, mutex* m)
+ 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;
@@ -188,71 +214,68 @@ namespace boost
}
}
};
+#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)
{
- using namespace chrono;
- boost::detail::thread_data_base* const thread_info=boost::detail::get_current_thread_data();
-
- if(thread_info)
- {
- unique_lock<mutex> lk(thread_info->sleep_mutex);
- while(cv_status::no_timeout==thread_info->sleep_condition.wait_for(lk,ns)) {}
- }
- else
- {
- if (ns >= nanoseconds::zero())
- {
-
- # if defined(BOOST_HAS_PTHREAD_DELAY_NP)
- timespec ts;
- ts.tv_sec = static_cast<long>(duration_cast<seconds>(ns).count());
- ts.tv_nsec = static_cast<long>((ns - seconds(ts.tv_sec)).count());
- BOOST_VERIFY(!pthread_delay_np(&ts));
- # elif defined(BOOST_HAS_NANOSLEEP)
- timespec ts;
- ts.tv_sec = static_cast<long>(duration_cast<seconds>(ns).count());
- ts.tv_nsec = static_cast<long>((ns - seconds(ts.tv_sec)).count());
- // nanosleep takes a timespec that is an offset, not
- // an absolute time.
- nanosleep(&ts, 0);
- # else
- mutex mx;
- mutex::scoped_lock lock(mx);
- condition_variable cond;
- cond.wait_for(lock, ns);
- # endif
- }
- }
+ 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::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<typename TimeDuration>
- inline void sleep(TimeDuration const& rel_time)
+ template<>
+#endif
+ inline void sleep(system_time const& abs_time)
{
- this_thread::sleep(get_system_time()+rel_time);
+ return boost::this_thread::hiden::sleep_until(boost::detail::to_timespec(abs_time));
}
- template<>
- void BOOST_THREAD_DECL sleep(system_time const& abs_time);
-#else
- void BOOST_THREAD_DECL sleep(system_time const& abs_time);
-
template<typename TimeDuration>
inline BOOST_SYMBOL_VISIBLE void sleep(TimeDuration const& rel_time)
{
this_thread::sleep(get_system_time()+rel_time);
}
-#endif
- }
+#endif // BOOST_THREAD_USES_DATETIME
+ } // this_thread
}
#include <boost/config/abi_suffix.hpp>
diff --git a/3rdParty/Boost/src/boost/thread/pthread/timespec.hpp b/3rdParty/Boost/src/boost/thread/pthread/timespec.hpp
index d7465c1..82f50f6 100644
--- a/3rdParty/Boost/src/boost/thread/pthread/timespec.hpp
+++ b/3rdParty/Boost/src/boost/thread/pthread/timespec.hpp
@@ -1,34 +1,118 @@
#ifndef BOOST_THREAD_PTHREAD_TIMESPEC_HPP
#define BOOST_THREAD_PTHREAD_TIMESPEC_HPP
-// (C) Copyright 2007-8 Anthony Williams
+// (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
- {
- inline struct timespec get_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;
- }
+ 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>
diff --git a/3rdParty/Boost/src/boost/thread/recursive_mutex.hpp b/3rdParty/Boost/src/boost/thread/recursive_mutex.hpp
index d5f6116..e716a19 100644
--- a/3rdParty/Boost/src/boost/thread/recursive_mutex.hpp
+++ b/3rdParty/Boost/src/boost/thread/recursive_mutex.hpp
@@ -3,7 +3,7 @@
// recursive_mutex.hpp
//
-// (C) Copyright 2007 Anthony Williams
+// (C) Copyright 2007 Anthony Williams
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -18,4 +18,47 @@
#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/3rdParty/Boost/src/boost/thread/shared_mutex.hpp b/3rdParty/Boost/src/boost/thread/shared_mutex.hpp
index e85e269..b968f2a 100644
--- a/3rdParty/Boost/src/boost/thread/shared_mutex.hpp
+++ b/3rdParty/Boost/src/boost/thread/shared_mutex.hpp
@@ -18,9 +18,32 @@
#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
+{
+ 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/3rdParty/Boost/src/boost/thread/thread.hpp b/3rdParty/Boost/src/boost/thread/thread.hpp
index ee15c6e..3e63b42 100644
--- a/3rdParty/Boost/src/boost/thread/thread.hpp
+++ b/3rdParty/Boost/src/boost/thread/thread.hpp
@@ -9,20 +9,8 @@
// 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>
-#include <boost/thread/detail/thread_interruption.hpp>
+#include <boost/thread/thread_only.hpp>
#include <boost/thread/detail/thread_group.hpp>
-#include <boost/thread/v2/thread.hpp>
#endif
diff --git a/3rdParty/Boost/src/boost/thread/thread_only.hpp b/3rdParty/Boost/src/boost/thread/thread_only.hpp
new file mode 100644
index 0000000..0d0c070
--- /dev/null
+++ b/3rdParty/Boost/src/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/3rdParty/Boost/src/boost/thread/v2/thread.hpp b/3rdParty/Boost/src/boost/thread/v2/thread.hpp
index d686c5f..181661a 100644
--- a/3rdParty/Boost/src/boost/thread/v2/thread.hpp
+++ b/3rdParty/Boost/src/boost/thread/v2/thread.hpp
@@ -9,26 +9,77 @@
#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/locks.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;
- nanoseconds ns = duration_cast<nanoseconds> (d);
- if (ns < d) ++ns;
- sleep_for(ns);
+ 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)
{
@@ -40,6 +91,28 @@ namespace boost
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)
@@ -47,6 +120,19 @@ namespace boost
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
}
diff --git a/3rdParty/Boost/src/boost/thread/win32/basic_recursive_mutex.hpp b/3rdParty/Boost/src/boost/thread/win32/basic_recursive_mutex.hpp
index e259121..cfdfa04 100644
--- a/3rdParty/Boost/src/boost/thread/win32/basic_recursive_mutex.hpp
+++ b/3rdParty/Boost/src/boost/thread/win32/basic_recursive_mutex.hpp
@@ -58,6 +58,7 @@ namespace boost
recursion_count=1;
}
}
+#if defined BOOST_THREAD_USES_DATETIME
bool timed_lock(::boost::system_time const& target)
{
long const current_thread_id=win32::GetCurrentThreadId();
@@ -68,6 +69,7 @@ namespace boost
{
return timed_lock(get_system_time()+timeout);
}
+#endif
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
@@ -114,6 +116,7 @@ namespace boost
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))
@@ -124,6 +127,7 @@ namespace boost
}
return false;
}
+#endif
template <typename TP>
bool try_timed_lock_until(long current_thread_id,TP const& target)
{
diff --git a/3rdParty/Boost/src/boost/thread/win32/basic_timed_mutex.hpp b/3rdParty/Boost/src/boost/thread/win32/basic_timed_mutex.hpp
index 6a43077..01db033 100644
--- a/3rdParty/Boost/src/boost/thread/win32/basic_timed_mutex.hpp
+++ b/3rdParty/Boost/src/boost/thread/win32/basic_timed_mutex.hpp
@@ -14,7 +14,9 @@
#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>
@@ -79,8 +81,10 @@ namespace boost
do
{
- BOOST_VERIFY(win32::WaitForSingleObject(
- sem,::boost::detail::win32::infinite)==0);
+ unsigned const retval(win32::WaitForSingleObject(sem, ::boost::detail::win32::infinite));
+ 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);
}
@@ -91,10 +95,13 @@ namespace boost
{
for(;;)
{
- long const new_count=(old_count&lock_flag_value)?(old_count+1):(old_count|lock_flag_value);
+ 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;
@@ -118,6 +125,7 @@ namespace boost
}
+#if defined BOOST_THREAD_USES_DATETIME
bool timed_lock(::boost::system_time const& wait_until)
{
if(try_lock())
@@ -147,7 +155,6 @@ namespace boost
return true;
}
-
template<typename Duration>
bool timed_lock(Duration const& timeout)
{
@@ -158,7 +165,7 @@ namespace boost
{
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)
diff --git a/3rdParty/Boost/src/boost/thread/win32/condition_variable.hpp b/3rdParty/Boost/src/boost/thread/win32/condition_variable.hpp
index 4c893ad..57aaf8c 100644
--- a/3rdParty/Boost/src/boost/thread/win32/condition_variable.hpp
+++ b/3rdParty/Boost/src/boost/thread/win32/condition_variable.hpp
@@ -11,9 +11,13 @@
#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>
@@ -187,18 +191,17 @@ namespace boost
struct entry_manager
{
entry_ptr const entry;
+ boost::mutex& internal_mutex;
BOOST_THREAD_NO_COPYABLE(entry_manager)
- entry_manager(entry_ptr const& entry_):
- entry(entry_)
+ entry_manager(entry_ptr const& entry_, boost::mutex& mutex_):
+ entry(entry_), internal_mutex(mutex_)
{}
~entry_manager()
{
- if(! entry->is_notified())
- {
+ boost::lock_guard<boost::mutex> internal_lock(internal_mutex);
entry->remove_waiter();
- }
}
list_entry* operator->()
@@ -214,7 +217,7 @@ namespace boost
{
relocker<lock_type> locker(lock);
- entry_manager entry(get_wait_entry());
+ entry_manager entry(get_wait_entry(), internal_mutex);
locker.unlock();
@@ -321,6 +324,7 @@ namespace boost
}
+#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);
@@ -333,7 +337,16 @@ namespace boost
template<typename duration_type>
bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration)
{
- return do_wait(m,wait_duration.total_milliseconds());
+ 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>
@@ -351,7 +364,7 @@ namespace boost
{
return do_wait(m,wait_duration.total_milliseconds(),pred);
}
-
+#endif
#ifdef BOOST_THREAD_USES_CHRONO
template <class Clock, class Duration>
@@ -361,7 +374,11 @@ namespace boost
const chrono::time_point<Clock, Duration>& t)
{
using namespace chrono;
- do_wait(lock, ceil<milliseconds>(t-Clock::now()).count());
+ 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;
}
@@ -373,6 +390,10 @@ namespace boost
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 :
@@ -400,7 +421,7 @@ namespace boost
const chrono::duration<Rep, Period>& d,
Predicate pred)
{
- return wait_until(lock, chrono::steady_clock::now() + d, pred);
+ return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred));
}
#endif
};
@@ -428,6 +449,7 @@ namespace boost
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)
{
@@ -463,6 +485,7 @@ namespace boost
{
return do_wait(m,wait_duration.total_milliseconds(),pred);
}
+#endif
#ifdef BOOST_THREAD_USES_CHRONO
template <class lock_type, class Clock, class Duration>
@@ -472,7 +495,11 @@ namespace boost
const chrono::time_point<Clock, Duration>& t)
{
using namespace chrono;
- do_wait(lock, ceil<milliseconds>(t-Clock::now()).count());
+ 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;
}
@@ -484,6 +511,9 @@ namespace boost
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 :
@@ -512,7 +542,7 @@ namespace boost
const chrono::duration<Rep, Period>& d,
Predicate pred)
{
- return wait_until(lock, chrono::steady_clock::now() + d, pred);
+ return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred));
}
#endif
};
diff --git a/3rdParty/Boost/src/boost/thread/win32/mutex.hpp b/3rdParty/Boost/src/boost/thread/win32/mutex.hpp
index 85a00e2..0154478 100644
--- a/3rdParty/Boost/src/boost/thread/win32/mutex.hpp
+++ b/3rdParty/Boost/src/boost/thread/win32/mutex.hpp
@@ -8,7 +8,10 @@
#include <boost/thread/win32/basic_timed_mutex.hpp>
#include <boost/thread/exceptions.hpp>
-#include <boost/thread/locks.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>
@@ -33,8 +36,10 @@ namespace boost
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;
@@ -54,9 +59,11 @@ namespace boost
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
};
}
diff --git a/3rdParty/Boost/src/boost/thread/win32/once.hpp b/3rdParty/Boost/src/boost/thread/win32/once.hpp
index 3066b50..0ed56a5 100644
--- a/3rdParty/Boost/src/boost/thread/win32/once.hpp
+++ b/3rdParty/Boost/src/boost/thread/win32/once.hpp
@@ -5,7 +5,7 @@
//
// (C) Copyright 2005-7 Anthony Williams
// (C) Copyright 2005 John Maddock
-// (C) Copyright 2011-2012 Vicente J. Botet Escriba
+// (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
@@ -18,6 +18,11 @@
#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>
@@ -31,6 +36,16 @@ namespace std
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
@@ -39,12 +54,12 @@ namespace boost
BOOST_CONSTEXPR once_flag() BOOST_NOEXCEPT
: status(0), count(0)
{}
- private:
long status;
long count;
- template<typename Function>
- friend
- void call_once(once_flag& flag,Function f);
+ 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()
@@ -59,6 +74,17 @@ namespace boost
#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
@@ -135,94 +161,928 @@ namespace boost
::boost::detail::win32::event_initially_reset,
mutex_name);
}
- }
+ 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::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+//#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::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+ 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::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+#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:
- long const function_complete_flag_value=0xc15730e2;
- long const running_value=0x7f0725e3;
- long status;
- bool counted=false;
- detail::win32::handle_manager event_handle;
- detail::once_char_type mutex_name[detail::once_mutex_name_length];
- mutex_name[0]=0;
+ 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::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+ 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::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+ 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::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+ 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::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+#elif defined BOOST_NO_CXX11_RVALUE_REFERENCES
- while((status=::boost::detail::interlocked_read_acquire(&flag.status))
- !=function_complete_flag_value)
+ 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)
{
- status=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&flag.status,running_value,0);
- if(!status)
+ 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)
{
-#ifndef BOOST_NO_EXCEPTIONS
- try // BOOST_NO_EXCEPTIONS protected
+ 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::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+ 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::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+ 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::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+ 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::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
#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))
{
- if(!event_handle)
+ BOOST_TRY
{
- event_handle=detail::open_once_event(mutex_name,&flag);
+ f();
}
- if(event_handle)
+ BOOST_CATCH(...)
{
- ::boost::detail::win32::ResetEvent(event_handle);
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
}
- f();
- if(!counted)
+ 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::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+ 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::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+ 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
{
- BOOST_INTERLOCKED_INCREMENT(&flag.count);
- counted=true;
+ f(
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
+ thread_detail::decay_copy(boost::forward<T2>(p2))
+ );
}
- BOOST_INTERLOCKED_EXCHANGE(&flag.status,function_complete_flag_value);
- if(!event_handle &&
- (::boost::detail::interlocked_read_acquire(&flag.count)>1))
+ BOOST_CATCH(...)
{
- event_handle=detail::create_once_event(mutex_name,&flag);
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
}
- if(event_handle)
+ 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)
{
- ::boost::detail::win32::SetEvent(event_handle);
+ break;
}
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+ 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;
}
-#ifndef BOOST_NO_EXCEPTIONS
- catch(...) // BOOST_NO_EXCEPTIONS protected
+ if(!ctx.counted)
{
- BOOST_INTERLOCKED_EXCHANGE(&flag.status,0);
- if(!event_handle)
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
{
- event_handle=detail::open_once_event(mutex_name,&flag);
+ break;
}
- if(event_handle)
+ if(!ctx.event_handle)
{
- ::boost::detail::win32::SetEvent(event_handle);
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
}
- throw; // BOOST_NO_EXCEPTIONS protected
}
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
#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::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
- if(!counted)
+ 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);
- counted=true;
- status=::boost::detail::interlocked_read_acquire(&flag.status);
- if(status==function_complete_flag_value)
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
{
break;
}
- if(!event_handle)
+ if(!ctx.event_handle)
{
- event_handle=detail::create_once_event(mutex_name,&flag);
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
continue;
}
}
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
- event_handle,::boost::detail::win32::infinite));
+ ctx.event_handle,::boost::detail::win32::infinite));
}
}
+ 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::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+ 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::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+
+#endif
+#endif
}
#include <boost/config/abi_suffix.hpp>
diff --git a/3rdParty/Boost/src/boost/thread/win32/recursive_mutex.hpp b/3rdParty/Boost/src/boost/thread/win32/recursive_mutex.hpp
index 5144e77..1f0f7f5 100644
--- a/3rdParty/Boost/src/boost/thread/win32/recursive_mutex.hpp
+++ b/3rdParty/Boost/src/boost/thread/win32/recursive_mutex.hpp
@@ -12,7 +12,10 @@
#include <boost/thread/win32/basic_recursive_mutex.hpp>
#include <boost/thread/exceptions.hpp>
-#include <boost/thread/locks.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>
@@ -32,8 +35,10 @@ namespace boost
::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;
@@ -52,9 +57,11 @@ namespace boost
::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
};
}
diff --git a/3rdParty/Boost/src/boost/thread/win32/shared_mutex.hpp b/3rdParty/Boost/src/boost/thread/win32/shared_mutex.hpp
index fef2d5b..252174f 100644
--- a/3rdParty/Boost/src/boost/thread/win32/shared_mutex.hpp
+++ b/3rdParty/Boost/src/boost/thread/win32/shared_mutex.hpp
@@ -95,7 +95,7 @@ namespace boost
detail::win32::release_semaphore(semaphores[exclusive_sem],LONG_MAX);
boost::throw_exception(thread_resource_error());
}
- state_data state_={0};
+ state_data state_={0,0,0,0,0,0};
state=state_;
}
@@ -133,15 +133,19 @@ namespace boost
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(;;)
@@ -220,6 +224,7 @@ namespace boost
BOOST_ASSERT(res==0);
}
}
+#endif
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
@@ -378,14 +383,20 @@ namespace boost
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()
{
@@ -413,6 +424,7 @@ namespace boost
}
+#if defined BOOST_THREAD_USES_DATETIME
bool timed_lock(boost::system_time const& wait_until)
{
for(;;)
@@ -459,6 +471,7 @@ namespace boost
{
for(;;)
{
+ bool must_notify = false;
state_data new_state=old_state;
if(new_state.shared_count || new_state.exclusive)
{
@@ -467,6 +480,7 @@ namespace boost
if(!--new_state.exclusive_waiting)
{
new_state.exclusive_waiting_blocked=false;
+ must_notify = true;
}
}
}
@@ -476,6 +490,11 @@ namespace boost
}
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;
@@ -491,7 +510,7 @@ namespace boost
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)
@@ -568,6 +587,7 @@ namespace boost
{
for(;;)
{
+ bool must_notify = false;
state_data new_state=old_state;
if(new_state.shared_count || new_state.exclusive)
{
@@ -576,6 +596,7 @@ namespace boost
if(!--new_state.exclusive_waiting)
{
new_state.exclusive_waiting_blocked=false;
+ must_notify = true;
}
}
}
@@ -585,6 +606,10 @@ namespace boost
}
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;
@@ -724,9 +749,11 @@ namespace boost
if(last_reader)
{
release_waiters(old_state);
- } else {
- release_waiters(old_state);
}
+ // #7720
+ //else {
+ // release_waiters(old_state);
+ //}
break;
}
old_state=current_state;
diff --git a/3rdParty/Boost/src/boost/thread/win32/thread_data.hpp b/3rdParty/Boost/src/boost/thread/win32/thread_data.hpp
index 18fd7cb..1d4f572 100644
--- a/3rdParty/Boost/src/boost/thread/win32/thread_data.hpp
+++ b/3rdParty/Boost/src/boost/thread/win32/thread_data.hpp
@@ -22,6 +22,11 @@
#include <boost/config/abi_prefix.hpp>
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4251)
+#endif
+
namespace boost
{
class condition_variable;
@@ -67,6 +72,7 @@ namespace boost
namespace detail
{
+ struct shared_state_base;
struct tss_cleanup_function;
struct thread_exit_callback_node;
struct tss_data_node
@@ -88,24 +94,34 @@ namespace boost
{
long count;
detail::win32::handle_manager thread_handle;
- detail::win32::handle_manager interruption_handle;
boost::detail::thread_exit_callback_node* thread_exit_callbacks;
std::map<void const*,boost::detail::tss_data_node> tss_data;
- bool interruption_enabled;
unsigned id;
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(detail::win32::invalid_handle_value),
- interruption_handle(create_anonymous_event(detail::win32::manual_reset_event,detail::win32::event_initially_reset)),
thread_exit_callbacks(0),tss_data(),
- interruption_enabled(true),
id(0),
- notify()
+ 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();
@@ -122,27 +138,34 @@ namespace boost
}
}
+#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;
- void notify_all_at_thread_exit(condition_variable* cv, mutex* m)
+ 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
{
- unsigned long start;
+ win32::ticks_type start;
uintmax_t milliseconds;
bool relative;
boost::system_time abs_time;
@@ -150,14 +173,14 @@ namespace boost
static unsigned long const max_non_infinite_wait=0xfffffffe;
timeout(uintmax_t milliseconds_):
- start(win32::GetTickCount()),
+ start(win32::GetTickCount64()()),
milliseconds(milliseconds_),
relative(true),
abs_time(boost::get_system_time())
{}
timeout(boost::system_time const& abs_time_):
- start(win32::GetTickCount()),
+ start(win32::GetTickCount64()()),
milliseconds(0),
relative(false),
abs_time(abs_time_)
@@ -182,8 +205,8 @@ namespace boost
}
else if(relative)
{
- unsigned long const now=win32::GetTickCount();
- unsigned long const elapsed=now-start;
+ win32::ticks_type const now=win32::GetTickCount64()();
+ win32::ticks_type const elapsed=now-start;
return remaining_time((elapsed<milliseconds)?(milliseconds-elapsed):0);
}
else
@@ -235,7 +258,6 @@ namespace boost
{
interruptible_wait(detail::win32::invalid_handle_value,abs_time);
}
-
template<typename TimeDuration>
inline BOOST_SYMBOL_VISIBLE void sleep(TimeDuration const& rel_time)
{
@@ -251,10 +273,41 @@ namespace boost
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);
+ }
+#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/3rdParty/Boost/src/boost/thread/win32/thread_heap_alloc.hpp b/3rdParty/Boost/src/boost/thread/win32/thread_heap_alloc.hpp
index 9b6d390..610fe32 100644
--- a/3rdParty/Boost/src/boost/thread/win32/thread_heap_alloc.hpp
+++ b/3rdParty/Boost/src/boost/thread/win32/thread_heap_alloc.hpp
@@ -5,10 +5,12 @@
#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>
@@ -75,20 +77,17 @@ namespace boost
inline T* heap_new()
{
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
-#ifndef BOOST_NO_EXCEPTIONS
- try // BOOST_NO_EXCEPTIONS protected
-#endif
+ BOOST_TRY
{
T* const data=new (heap_memory) T();
return data;
}
-#ifndef BOOST_NO_EXCEPTIONS
- catch(...) // BOOST_NO_EXCEPTIONS protected
+ BOOST_CATCH(...)
{
free_raw_heap_memory(heap_memory);
- throw; // BOOST_NO_EXCEPTIONS protected
+ BOOST_RETHROW
}
-#endif
+ BOOST_CATCH_END
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
@@ -96,159 +95,135 @@ namespace boost
inline T* heap_new(A1&& a1)
{
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
-#ifndef BOOST_NO_EXCEPTIONS
- try // BOOST_NO_EXCEPTIONS protected
-#endif
+ BOOST_TRY
{
T* const data=new (heap_memory) T(static_cast<A1&&>(a1));
return data;
}
-#ifndef BOOST_NO_EXCEPTIONS
- catch(...) // BOOST_NO_EXCEPTIONS protected
+ BOOST_CATCH(...)
{
free_raw_heap_memory(heap_memory);
- throw; // BOOST_NO_EXCEPTIONS protected
+ BOOST_RETHROW
}
-#endif
+ 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));
-#ifndef BOOST_NO_EXCEPTIONS
- try // BOOST_NO_EXCEPTIONS protected
-#endif
+ BOOST_TRY
{
T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2));
return data;
}
-#ifndef BOOST_NO_EXCEPTIONS
- catch(...) // BOOST_NO_EXCEPTIONS protected
+ BOOST_CATCH(...)
{
free_raw_heap_memory(heap_memory);
- throw; // BOOST_NO_EXCEPTIONS protected
+ BOOST_RETHROW
}
-#endif
+ 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));
-#ifndef BOOST_NO_EXCEPTIONS
- try // BOOST_NO_EXCEPTIONS protected
-#endif
+ BOOST_TRY
{
T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2),
static_cast<A3&&>(a3));
return data;
}
-#ifndef BOOST_NO_EXCEPTIONS
- catch(...) // BOOST_NO_EXCEPTIONS protected
+ BOOST_CATCH(...)
{
free_raw_heap_memory(heap_memory);
- throw; // BOOST_NO_EXCEPTIONS protected
+ BOOST_RETHROW
}
-#endif
+ 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));
-#ifndef BOOST_NO_EXCEPTIONS
- try // BOOST_NO_EXCEPTIONS protected
-#endif
+ 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;
}
-#ifndef BOOST_NO_EXCEPTIONS
- catch(...) // BOOST_NO_EXCEPTIONS protected
+ BOOST_CATCH(...)
{
free_raw_heap_memory(heap_memory);
- throw; // BOOST_NO_EXCEPTIONS protected
+ BOOST_RETHROW
}
-#endif
+ 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));
-#ifndef BOOST_NO_EXCEPTIONS
- try // BOOST_NO_EXCEPTIONS protected
-#endif
+ BOOST_TRY
{
T* const data=new (heap_memory) T(a1);
return data;
}
-#ifndef BOOST_NO_EXCEPTIONS
- catch(...) // BOOST_NO_EXCEPTIONS protected
+ BOOST_CATCH(...)
{
free_raw_heap_memory(heap_memory);
- throw; // BOOST_NO_EXCEPTIONS protected
+ BOOST_RETHROW
}
-#endif
+ 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));
-#ifndef BOOST_NO_EXCEPTIONS
- try // BOOST_NO_EXCEPTIONS protected
-#endif
+ BOOST_TRY
{
T* const data=new (heap_memory) T(a1,a2);
return data;
}
-#ifndef BOOST_NO_EXCEPTIONS
- catch(...) // BOOST_NO_EXCEPTIONS protected
+ BOOST_CATCH(...)
{
free_raw_heap_memory(heap_memory);
- throw; // BOOST_NO_EXCEPTIONS protected
+ BOOST_RETHROW
}
-#endif
+ 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));
-#ifndef BOOST_NO_EXCEPTIONS
- try // BOOST_NO_EXCEPTIONS protected
-#endif
+ BOOST_TRY
{
T* const data=new (heap_memory) T(a1,a2,a3);
return data;
}
-#ifndef BOOST_NO_EXCEPTIONS
- catch(...) // BOOST_NO_EXCEPTIONS protected
+ BOOST_CATCH(...)
{
free_raw_heap_memory(heap_memory);
- throw; // BOOST_NO_EXCEPTIONS protected
+ BOOST_RETHROW
}
-#endif
+ 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));
-#ifndef BOOST_NO_EXCEPTIONS
- try // BOOST_NO_EXCEPTIONS protected
-#endif
+ BOOST_TRY
{
T* const data=new (heap_memory) T(a1,a2,a3,a4);
return data;
}
-#ifndef BOOST_NO_EXCEPTIONS
- catch(...) // BOOST_NO_EXCEPTIONS protected
+ BOOST_CATCH(...)
{
free_raw_heap_memory(heap_memory);
- throw; // BOOST_NO_EXCEPTIONS protected
+ BOOST_RETHROW
}
-#endif
+ BOOST_CATCH_END
}
diff --git a/3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp b/3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp
index c0dba11..fcf59b3 100644
--- a/3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp
+++ b/3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp
@@ -15,6 +15,7 @@
#include <boost/assert.hpp>
#include <boost/thread/exceptions.hpp>
#include <boost/detail/interlocked.hpp>
+//#include <boost/detail/winapi/synchronization.hpp>
#include <algorithm>
#if defined( BOOST_USE_WINDOWS_H )
@@ -26,13 +27,14 @@ namespace boost
{
namespace win32
{
- typedef ULONG_PTR ulong_ptr;
typedef HANDLE handle;
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;
+
# ifdef BOOST_NO_ANSI_APIS
using ::CreateMutexW;
@@ -60,7 +62,6 @@ namespace boost
using ::SleepEx;
using ::Sleep;
using ::QueueUserAPC;
- using ::GetTickCount;
}
}
}
@@ -88,13 +89,13 @@ typedef void* HANDLE;
# endif
# endif
+
namespace boost
{
namespace detail
{
namespace win32
{
-
# ifdef _WIN64
typedef unsigned __int64 ulong_ptr;
# else
@@ -106,6 +107,7 @@ namespace boost
handle const invalid_handle_value=(handle)(-1);
unsigned const event_modify_state=2;
unsigned const synchronize=0x100000u;
+ unsigned const wait_abandoned=0x00000080u;
extern "C"
{
@@ -132,8 +134,6 @@ namespace boost
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) unsigned long __stdcall GetTickCount();
-
# ifndef UNDER_CE
__declspec(dllimport) unsigned long __stdcall GetCurrentProcessId();
__declspec(dllimport) unsigned long __stdcall GetCurrentThreadId();
@@ -165,7 +165,88 @@ namespace boost
{
namespace win32
{
- enum event_type
+ typedef unsigned __int64 ticks_type;
+ namespace detail { typedef int (__stdcall *farproc_t)(); typedef ticks_type (__stdcall *gettickcount64_t)(); }
+ extern "C"
+ {
+ __declspec(dllimport) detail::farproc_t __stdcall GetProcAddress(void *, const char *);
+#if !defined(BOOST_NO_ANSI_APIS)
+ __declspec(dllimport) void * __stdcall GetModuleHandleA(const char *);
+#else
+ __declspec(dllimport) void * __stdcall GetModuleHandleW(const wchar_t *);
+#endif
+ int __stdcall GetTickCount();
+ long _InterlockedCompareExchange(long volatile *, long, long);
+#pragma intrinsic(_InterlockedCompareExchange)
+ }
+ // 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;
+ }
+ inline detail::gettickcount64_t GetTickCount64()
+ {
+ static detail::gettickcount64_t gettickcount64impl;
+ if(gettickcount64impl)
+ return gettickcount64impl;
+ detail::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;
+ return gettickcount64impl;
+ }
+
+ enum event_type
{
auto_reset_event=false,
manual_reset_event=true
@@ -232,7 +313,7 @@ namespace boost
BOOST_VERIFY(ReleaseSemaphore(semaphore,count,0)!=0);
}
- class handle_manager
+ class BOOST_THREAD_DECL handle_manager
{
private:
handle handle_to_manage;
diff --git a/3rdParty/Boost/src/boost/thread/xtime.hpp b/3rdParty/Boost/src/boost/thread/xtime.hpp
index 1ca996f..9c6a359 100644
--- a/3rdParty/Boost/src/boost/thread/xtime.hpp
+++ b/3rdParty/Boost/src/boost/thread/xtime.hpp
@@ -9,6 +9,7 @@
#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>
@@ -88,5 +89,5 @@ inline int xtime_cmp(const xtime& xt1, const xtime& xt2)
} // namespace boost
#include <boost/config/abi_suffix.hpp>
-
+#endif
#endif //BOOST_XTIME_WEK070601_HPP