summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '3rdParty/Boost/src/boost/signals2/detail')
-rw-r--r--3rdParty/Boost/src/boost/signals2/detail/auto_buffer.hpp1138
-rw-r--r--3rdParty/Boost/src/boost/signals2/detail/foreign_ptr.hpp185
-rw-r--r--3rdParty/Boost/src/boost/signals2/detail/lwm_nop.hpp38
-rw-r--r--3rdParty/Boost/src/boost/signals2/detail/lwm_pthreads.hpp78
-rw-r--r--3rdParty/Boost/src/boost/signals2/detail/lwm_win32_cs.hpp120
-rw-r--r--3rdParty/Boost/src/boost/signals2/detail/null_output_iterator.hpp34
-rw-r--r--3rdParty/Boost/src/boost/signals2/detail/preprocessed_arg_type.hpp34
-rw-r--r--3rdParty/Boost/src/boost/signals2/detail/preprocessed_arg_type_template.hpp39
-rw-r--r--3rdParty/Boost/src/boost/signals2/detail/replace_slot_function.hpp32
-rw-r--r--3rdParty/Boost/src/boost/signals2/detail/result_type_wrapper.hpp72
-rw-r--r--3rdParty/Boost/src/boost/signals2/detail/signal_template.hpp859
-rw-r--r--3rdParty/Boost/src/boost/signals2/detail/signals_common.hpp77
-rw-r--r--3rdParty/Boost/src/boost/signals2/detail/signals_common_macros.hpp212
-rw-r--r--3rdParty/Boost/src/boost/signals2/detail/slot_call_iterator.hpp147
-rw-r--r--3rdParty/Boost/src/boost/signals2/detail/slot_groups.hpp235
-rw-r--r--3rdParty/Boost/src/boost/signals2/detail/slot_template.hpp187
-rw-r--r--3rdParty/Boost/src/boost/signals2/detail/tracked_objects_visitor.hpp98
-rw-r--r--3rdParty/Boost/src/boost/signals2/detail/unique_lock.hpp42
-rw-r--r--3rdParty/Boost/src/boost/signals2/detail/variadic_arg_type.hpp49
-rw-r--r--3rdParty/Boost/src/boost/signals2/detail/variadic_slot_invoker.hpp139
20 files changed, 3815 insertions, 0 deletions
diff --git a/3rdParty/Boost/src/boost/signals2/detail/auto_buffer.hpp b/3rdParty/Boost/src/boost/signals2/detail/auto_buffer.hpp
new file mode 100644
index 0000000..bf12e69
--- /dev/null
+++ b/3rdParty/Boost/src/boost/signals2/detail/auto_buffer.hpp
@@ -0,0 +1,1138 @@
+// Copyright Thorsten Ottosen, 2009.
+// Distributed under the 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_SIGNALS2_DETAIL_AUTO_BUFFER_HPP_25_02_2009
+#define BOOST_SIGNALS2_DETAIL_AUTO_BUFFER_HPP_25_02_2009
+
+#include <boost/detail/workaround.hpp>
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+#pragma warning(push)
+#pragma warning(disable:4996)
+#endif
+
+#include <boost/assert.hpp>
+#include <boost/iterator/reverse_iterator.hpp>
+#include <boost/iterator/iterator_traits.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/multi_index/detail/scope_guard.hpp>
+#include <boost/swap.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/type_traits/aligned_storage.hpp>
+#include <boost/type_traits/alignment_of.hpp>
+#include <boost/type_traits/has_nothrow_copy.hpp>
+#include <boost/type_traits/has_nothrow_assign.hpp>
+#include <boost/type_traits/has_trivial_assign.hpp>
+#include <boost/type_traits/has_trivial_constructor.hpp>
+#include <boost/type_traits/has_trivial_destructor.hpp>
+#include <algorithm>
+#include <cstring>
+#include <iterator>
+#include <memory>
+#include <stdexcept>
+
+namespace boost
+{
+namespace signals2
+{
+namespace detail
+{
+ //
+ // Policies for creating the stack buffer.
+ //
+ template< unsigned N >
+ struct store_n_objects
+ {
+ BOOST_STATIC_CONSTANT( unsigned, value = N );
+ };
+
+ template< unsigned N >
+ struct store_n_bytes
+ {
+ BOOST_STATIC_CONSTANT( unsigned, value = N );
+ };
+
+ namespace auto_buffer_detail
+ {
+ template< class Policy, class T >
+ struct compute_buffer_size
+ {
+ BOOST_STATIC_CONSTANT( unsigned, value = Policy::value * sizeof(T) );
+ };
+
+ template< unsigned N, class T >
+ struct compute_buffer_size< store_n_bytes<N>, T >
+ {
+ BOOST_STATIC_CONSTANT( unsigned, value = N );
+ };
+
+ template< class Policy, class T >
+ struct compute_buffer_objects
+ {
+ BOOST_STATIC_CONSTANT( unsigned, value = Policy::value );
+ };
+
+ template< unsigned N, class T >
+ struct compute_buffer_objects< store_n_bytes<N>, T >
+ {
+ BOOST_STATIC_CONSTANT( unsigned, value = N / sizeof(T) );
+ };
+ }
+
+ struct default_grow_policy
+ {
+ template< class SizeType >
+ static SizeType new_capacity( SizeType capacity )
+ {
+ //
+ // @remark: we grow the capacity quite agressively.
+ // this is justified since we aim to minimize
+ // heap-allocations, and because we mostly use
+ // the buffer locally.
+ return capacity * 4u;
+ }
+
+ template< class SizeType >
+ static bool should_shrink( SizeType size, SizeType capacity )
+ {
+ //
+ // @remark: when defining a new grow policy, one might
+ // choose that if the waated space is less
+ // than a certain percentage, then it is of
+ // little use to shrink.
+ //
+ return true;
+ }
+ };
+
+ template< class T,
+ class StackBufferPolicy = store_n_objects<256>,
+ class GrowPolicy = default_grow_policy,
+ class Allocator = std::allocator<T> >
+ class auto_buffer;
+
+
+
+ template
+ <
+ class T,
+ class StackBufferPolicy,
+ class GrowPolicy,
+ class Allocator
+ >
+ class auto_buffer : Allocator
+ {
+ private:
+ enum { N = auto_buffer_detail::
+ compute_buffer_objects<StackBufferPolicy,T>::value };
+
+ BOOST_STATIC_CONSTANT( bool, is_stack_buffer_empty = N == 0u );
+
+ typedef auto_buffer<T, store_n_objects<0>, GrowPolicy, Allocator>
+ local_buffer;
+
+ public:
+ typedef Allocator allocator_type;
+ typedef T value_type;
+ typedef typename Allocator::size_type size_type;
+ typedef typename Allocator::difference_type difference_type;
+ typedef T* pointer;
+ typedef typename Allocator::pointer allocator_pointer;
+ typedef const T* const_pointer;
+ typedef T& reference;
+ typedef const T& const_reference;
+ typedef pointer iterator;
+ typedef const_pointer const_iterator;
+ typedef boost::reverse_iterator<iterator> reverse_iterator;
+ typedef boost::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef typename boost::mpl::if_c< boost::has_trivial_assign<T>::value
+ && sizeof(T) <= sizeof(long double),
+ const value_type,
+ const_reference >::type
+ optimized_const_reference;
+ private:
+
+ pointer allocate( size_type capacity_arg )
+ {
+ if( capacity_arg > N )
+ return &*get_allocator().allocate( capacity_arg );
+ else
+ return static_cast<T*>( members_.address() );
+ }
+
+ void deallocate( pointer where, size_type capacity_arg )
+ {
+ if( capacity_arg <= N )
+ return;
+ get_allocator().deallocate( allocator_pointer(where), capacity_arg );
+ }
+
+ template< class I >
+ static void copy_impl( I begin, I end, pointer where, std::random_access_iterator_tag )
+ {
+ copy_rai( begin, end, where, boost::has_trivial_assign<T>() );
+ }
+
+ static void copy_rai( const T* begin, const T* end,
+ pointer where, const boost::true_type& )
+ {
+ std::memcpy( where, begin, sizeof(T) * std::distance(begin,end) );
+ }
+
+ template< class I, bool b >
+ static void copy_rai( I begin, I end,
+ pointer where, const boost::integral_constant<bool, b>& )
+ {
+ std::uninitialized_copy( begin, end, where );
+ }
+
+ template< class I >
+ static void copy_impl( I begin, I end, pointer where, std::bidirectional_iterator_tag )
+ {
+ std::uninitialized_copy( begin, end, where );
+ }
+
+ template< class I >
+ static void copy_impl( I begin, I end, pointer where )
+ {
+ copy_impl( begin, end, where,
+ typename std::iterator_traits<I>::iterator_category() );
+ }
+
+ template< class I, class I2 >
+ static void assign_impl( I begin, I end, I2 where )
+ {
+ assign_impl( begin, end, where, boost::has_trivial_assign<T>() );
+ }
+
+ template< class I, class I2 >
+ static void assign_impl( I begin, I end, I2 where, const boost::true_type& )
+ {
+ std::memcpy( where, begin, sizeof(T) * std::distance(begin,end) );
+ }
+
+ template< class I, class I2 >
+ static void assign_impl( I begin, I end, I2 where, const boost::false_type& )
+ {
+ for( ; begin != end; ++begin, ++where )
+ *where = *begin;
+ }
+
+ void unchecked_push_back_n( size_type n, const boost::true_type& )
+ {
+ std::uninitialized_fill( end(), end() + n, T() );
+ size_ += n;
+ }
+
+ void unchecked_push_back_n( size_type n, const boost::false_type& )
+ {
+ for( size_type i = 0u; i < n; ++i )
+ unchecked_push_back();
+ }
+
+ void auto_buffer_destroy( pointer where, const boost::false_type& )
+ {
+ (*where).~T();
+ }
+
+ void auto_buffer_destroy( pointer, const boost::true_type& )
+ { }
+
+ void auto_buffer_destroy( pointer where )
+ {
+ auto_buffer_destroy( where, boost::has_trivial_destructor<T>() );
+ }
+
+ void destroy_back_n( size_type n, const boost::false_type& )
+ {
+ BOOST_ASSERT( n > 0 );
+ pointer buffer = buffer_ + size_ - 1u;
+ pointer new_end = buffer - n;
+ for( ; buffer > new_end; --buffer )
+ auto_buffer_destroy( buffer );
+ }
+
+ void destroy_back_n( size_type n, const boost::true_type& )
+ { }
+
+ void destroy_back_n( size_type n )
+ {
+ destroy_back_n( n, boost::has_trivial_destructor<T>() );
+ }
+
+ void auto_buffer_destroy( const boost::false_type& x )
+ {
+ if( size_ )
+ destroy_back_n( size_, x );
+ deallocate( buffer_, members_.capacity_ );
+ }
+
+ void auto_buffer_destroy( const boost::true_type& )
+ {
+ deallocate( buffer_, members_.capacity_ );
+ }
+
+ pointer move_to_new_buffer( size_type new_capacity, const boost::false_type& )
+ {
+ pointer new_buffer = allocate( new_capacity ); // strong
+ boost::multi_index::detail::scope_guard guard =
+ boost::multi_index::detail::make_obj_guard( *this,
+ &auto_buffer::deallocate,
+ new_buffer,
+ new_capacity );
+ copy_impl( begin(), end(), new_buffer ); // strong
+ guard.dismiss(); // nothrow
+ return new_buffer;
+ }
+
+ pointer move_to_new_buffer( size_type new_capacity, const boost::true_type& )
+ {
+ pointer new_buffer = allocate( new_capacity ); // strong
+ copy_impl( begin(), end(), new_buffer ); // nothrow
+ return new_buffer;
+ }
+
+ void reserve_impl( size_type new_capacity )
+ {
+ pointer new_buffer = move_to_new_buffer( new_capacity,
+ boost::has_nothrow_copy<T>() );
+ (*this).~auto_buffer();
+ buffer_ = new_buffer;
+ members_.capacity_ = new_capacity;
+ BOOST_ASSERT( size_ <= members_.capacity_ );
+ }
+
+ size_type new_capacity_impl( size_type n )
+ {
+ BOOST_ASSERT( n > members_.capacity_ );
+ size_type new_capacity = GrowPolicy::new_capacity( members_.capacity_ );
+ // @todo: consider to check for allocator.max_size()
+ return (std::max)(new_capacity,n);
+ }
+
+ static void swap_helper( auto_buffer& l, auto_buffer& r,
+ const boost::true_type& )
+ {
+ BOOST_ASSERT( l.is_on_stack() && r.is_on_stack() );
+
+ auto_buffer temp( l.begin(), l.end() );
+ assign_impl( r.begin(), r.end(), l.begin() );
+ assign_impl( temp.begin(), temp.end(), r.begin() );
+ boost::swap( l.size_, r.size_ );
+ boost::swap( l.members_.capacity_, r.members_.capacity_ );
+ }
+
+ static void swap_helper( auto_buffer& l, auto_buffer& r,
+ const boost::false_type& )
+ {
+ BOOST_ASSERT( l.is_on_stack() && r.is_on_stack() );
+ size_type min_size = (std::min)(l.size_,r.size_);
+ size_type max_size = (std::max)(l.size_,r.size_);
+ size_type diff = max_size - min_size;
+ auto_buffer* smallest = l.size_ == min_size ? &l : &r;
+ auto_buffer* largest = smallest == &l ? &r : &l;
+
+ // @remark: the implementation below is not as fast
+ // as it could be if we assumed T had a default
+ // constructor.
+
+ size_type i = 0u;
+ for( ; i < min_size; ++i )
+ boost::swap( (*smallest)[i], (*largest)[i] );
+
+ for( ; i < max_size; ++i )
+ smallest->unchecked_push_back( (*largest)[i] );
+
+ largest->pop_back_n( diff );
+ boost::swap( l.members_.capacity_, r.members_.capacity_ );
+ }
+
+ void one_sided_swap( auto_buffer& temp ) // nothrow
+ {
+ BOOST_ASSERT( !temp.is_on_stack() );
+ this->~auto_buffer();
+ // @remark: must be nothrow
+ get_allocator() = temp.get_allocator();
+ members_.capacity_ = temp.members_.capacity_;
+ buffer_ = temp.buffer_;
+ BOOST_ASSERT( temp.size_ >= size_ + 1u );
+ size_ = temp.size_;
+ temp.buffer_ = 0;
+ BOOST_ASSERT( temp.is_valid() );
+ }
+
+ template< class I >
+ void insert_impl( const_iterator before, I begin_arg, I end_arg,
+ std::input_iterator_tag )
+ {
+ for( ; begin_arg != end_arg; ++begin_arg )
+ {
+ before = insert( before, *begin_arg );
+ ++before;
+ }
+ }
+
+ void grow_back( size_type n, const boost::true_type& )
+ {
+ BOOST_ASSERT( size_ + n <= members_.capacity_ );
+ size_ += n;
+ }
+
+ void grow_back( size_type n, const boost::false_type& )
+ {
+ unchecked_push_back_n(n);
+ }
+
+ void grow_back( size_type n )
+ {
+ grow_back( n, boost::has_trivial_constructor<T>() );
+ }
+
+ void grow_back_one( const boost::true_type& )
+ {
+ BOOST_ASSERT( size_ + 1 <= members_.capacity_ );
+ size_ += 1;
+ }
+
+ void grow_back_one( const boost::false_type& )
+ {
+ unchecked_push_back();
+ }
+
+ void grow_back_one()
+ {
+ grow_back_one( boost::has_trivial_constructor<T>() );
+ }
+
+ template< class I >
+ void insert_impl( const_iterator before, I begin_arg, I end_arg,
+ std::forward_iterator_tag )
+ {
+ difference_type n = std::distance(begin_arg, end_arg);
+
+ if( size_ + n <= members_.capacity_ )
+ {
+ bool is_back_insertion = before == cend();
+ if( !is_back_insertion )
+ {
+ grow_back( n );
+ iterator where = const_cast<T*>(before);
+ std::copy( before, cend() - n, where + n );
+ assign_impl( begin_arg, end_arg, where );
+ }
+ else
+ {
+ unchecked_push_back( begin_arg, end_arg );
+ }
+ BOOST_ASSERT( is_valid() );
+ return;
+ }
+
+ auto_buffer temp( new_capacity_impl( size_ + n ) );
+ temp.unchecked_push_back( cbegin(), before );
+ temp.unchecked_push_back( begin_arg, end_arg );
+ temp.unchecked_push_back( before, cend() );
+ one_sided_swap( temp );
+ BOOST_ASSERT( is_valid() );
+ }
+
+ public:
+ bool is_valid() const // invariant
+ {
+ // @remark: allowed for N==0 and when
+ // using a locally instance
+ // in insert()/one_sided_swap()
+ if( buffer_ == 0 )
+ return true;
+
+ if( members_.capacity_ < N )
+ return false;
+
+ if( !is_on_stack() && members_.capacity_ <= N )
+ return false;
+
+ if( buffer_ == members_.address() )
+ if( members_.capacity_ > N )
+ return false;
+
+ if( size_ > members_.capacity_ )
+ return false;
+
+ return true;
+ }
+
+ auto_buffer()
+ : members_( N ),
+ buffer_( static_cast<T*>(members_.address()) ),
+ size_( 0u )
+ {
+ BOOST_ASSERT( is_valid() );
+ }
+
+ auto_buffer( const auto_buffer& r )
+ : members_( (std::max)(r.size_,size_type(N)) ),
+ buffer_( allocate( members_.capacity_ ) ),
+ size_( 0 )
+ {
+ copy_impl( r.begin(), r.end(), buffer_ );
+ size_ = r.size_;
+ BOOST_ASSERT( is_valid() );
+ }
+
+ auto_buffer& operator=( const auto_buffer& r ) // basic
+ {
+ if( this == &r )
+ return *this;
+
+ difference_type diff = size_ - r.size_;
+ if( diff >= 0 )
+ {
+ pop_back_n( static_cast<size_type>(diff) );
+ assign_impl( r.begin(), r.end(), begin() );
+ }
+ else
+ {
+ if( members_.capacity_ >= r.size() )
+ {
+ unchecked_push_back_n( static_cast<size_type>(-diff) );
+ assign_impl( r.begin(), r.end(), begin() );
+ }
+ else
+ {
+ // @remark: we release memory as early as possible
+ // since we only give the basic guarantee
+ (*this).~auto_buffer();
+ buffer_ = 0;
+ pointer new_buffer = allocate( r.size() );
+ boost::multi_index::detail::scope_guard guard =
+ boost::multi_index::detail::make_obj_guard( *this,
+ &auto_buffer::deallocate,
+ new_buffer,
+ r.size() );
+ copy_impl( r.begin(), r.end(), new_buffer );
+ guard.dismiss();
+ buffer_ = new_buffer;
+ members_.capacity_ = r.size();
+ size_ = members_.capacity_;
+ }
+ }
+
+ BOOST_ASSERT( size() == r.size() );
+ BOOST_ASSERT( is_valid() );
+ return *this;
+ }
+
+ explicit auto_buffer( size_type capacity_arg )
+ : members_( (std::max)(capacity_arg, size_type(N)) ),
+ buffer_( allocate(members_.capacity_) ),
+ size_( 0 )
+ {
+ BOOST_ASSERT( is_valid() );
+ }
+
+ auto_buffer( size_type size_arg, optimized_const_reference init_value )
+ : members_( (std::max)(size_arg, size_type(N)) ),
+ buffer_( allocate(members_.capacity_) ),
+ size_( 0 )
+ {
+ std::uninitialized_fill( buffer_, buffer_ + size_arg, init_value );
+ size_ = size_arg;
+ BOOST_ASSERT( is_valid() );
+ }
+
+ auto_buffer( size_type capacity_arg, const allocator_type& a )
+ : allocator_type( a ),
+ members_( (std::max)(capacity_arg, size_type(N)) ),
+ buffer_( allocate(members_.capacity_) ),
+ size_( 0 )
+ {
+ BOOST_ASSERT( is_valid() );
+ }
+
+ auto_buffer( size_type size_arg, optimized_const_reference init_value,
+ const allocator_type& a )
+ : allocator_type( a ),
+ members_( (std::max)(size_arg, size_type(N)) ),
+ buffer_( allocate(members_.capacity_) ),
+ size_( 0 )
+ {
+ std::uninitialized_fill( buffer_, buffer_ + size_arg, init_value );
+ size_ = size_arg;
+ BOOST_ASSERT( is_valid() );
+ }
+
+ template< class ForwardIterator >
+ auto_buffer( ForwardIterator begin_arg, ForwardIterator end_arg )
+ :
+ members_( std::distance(begin_arg, end_arg) ),
+ buffer_( allocate(members_.capacity_) ),
+ size_( 0 )
+ {
+ copy_impl( begin_arg, end_arg, buffer_ );
+ size_ = members_.capacity_;
+ if( members_.capacity_ < N )
+ members_.capacity_ = N;
+ BOOST_ASSERT( is_valid() );
+ }
+
+ template< class ForwardIterator >
+ auto_buffer( ForwardIterator begin_arg, ForwardIterator end_arg,
+ const allocator_type& a )
+ : allocator_type( a ),
+ members_( std::distance(begin_arg, end_arg) ),
+ buffer_( allocate(members_.capacity_) ),
+ size_( 0 )
+ {
+ copy_impl( begin_arg, end_arg, buffer_ );
+ size_ = members_.capacity_;
+ if( members_.capacity_ < N )
+ members_.capacity_ = N;
+ BOOST_ASSERT( is_valid() );
+ }
+
+ ~auto_buffer()
+ {
+ BOOST_ASSERT( is_valid() );
+ if( buffer_ ) // do we need this check? Yes, but only
+ // for N = 0u + local instances in one_sided_swap()
+ auto_buffer_destroy( boost::has_trivial_destructor<T>() );
+ }
+
+ public:
+ bool empty() const
+ {
+ return size_ == 0;
+ }
+
+ bool full() const
+ {
+ return size_ == members_.capacity_;
+ }
+
+ bool is_on_stack() const
+ {
+ return members_.capacity_ <= N;
+ }
+
+ size_type size() const
+ {
+ return size_;
+ }
+
+ size_type capacity() const
+ {
+ return members_.capacity_;
+ }
+
+ public:
+ pointer data()
+ {
+ return buffer_;
+ }
+
+ const_pointer data() const
+ {
+ return buffer_;
+ }
+
+ allocator_type& get_allocator()
+ {
+ return static_cast<allocator_type&>(*this);
+ }
+
+ const allocator_type& get_allocator() const
+ {
+ return static_cast<const allocator_type&>(*this);
+ }
+
+ public:
+ iterator begin()
+ {
+ return buffer_;
+ }
+
+ const_iterator begin() const
+ {
+ return buffer_;
+ }
+
+ iterator end()
+ {
+ return buffer_ + size_;
+ }
+
+ const_iterator end() const
+ {
+ return buffer_ + size_;
+ }
+
+ reverse_iterator rbegin()
+ {
+ return reverse_iterator(end());
+ }
+
+ const_reverse_iterator rbegin() const
+ {
+ return const_reverse_iterator(end());
+ }
+
+ reverse_iterator rend()
+ {
+ return reverse_iterator(begin());
+ }
+
+ const_reverse_iterator rend() const
+ {
+ return const_reverse_iterator(begin());
+ }
+
+ const_iterator cbegin() const
+ {
+ return const_cast<const auto_buffer*>(this)->begin();
+ }
+
+ const_iterator cend() const
+ {
+ return const_cast<const auto_buffer*>(this)->end();
+ }
+
+ const_reverse_iterator crbegin() const
+ {
+ return const_cast<const auto_buffer*>(this)->rbegin();
+ }
+
+ const_reverse_iterator crend() const
+ {
+ return const_cast<const auto_buffer*>(this)->rend();
+ }
+
+ public:
+ reference front()
+ {
+ return buffer_[0];
+ }
+
+ optimized_const_reference front() const
+ {
+ return buffer_[0];
+ }
+
+ reference back()
+ {
+ return buffer_[size_-1];
+ }
+
+ optimized_const_reference back() const
+ {
+ return buffer_[size_-1];
+ }
+
+ reference operator[]( size_type n )
+ {
+ BOOST_ASSERT( n < size_ );
+ return buffer_[n];
+ }
+
+ optimized_const_reference operator[]( size_type n ) const
+ {
+ BOOST_ASSERT( n < size_ );
+ return buffer_[n];
+ }
+
+ void unchecked_push_back()
+ {
+ BOOST_ASSERT( !full() );
+ new (buffer_ + size_) T;
+ ++size_;
+ }
+
+ void unchecked_push_back_n( size_type n )
+ {
+ BOOST_ASSERT( size_ + n <= members_.capacity_ );
+ unchecked_push_back_n( n, boost::has_trivial_assign<T>() );
+ }
+
+ void unchecked_push_back( optimized_const_reference x ) // non-growing
+ {
+ BOOST_ASSERT( !full() );
+ new (buffer_ + size_) T( x );
+ ++size_;
+ }
+
+ template< class ForwardIterator >
+ void unchecked_push_back( ForwardIterator begin_arg,
+ ForwardIterator end_arg ) // non-growing
+ {
+ BOOST_ASSERT( size_ + std::distance(begin_arg, end_arg) <= members_.capacity_ );
+ copy_impl( begin_arg, end_arg, buffer_ + size_ );
+ size_ += std::distance(begin_arg, end_arg);
+ }
+
+ void reserve_precisely( size_type n )
+ {
+ BOOST_ASSERT( members_.capacity_ >= N );
+
+ if( n <= members_.capacity_ )
+ return;
+ reserve_impl( n );
+ BOOST_ASSERT( members_.capacity_ == n );
+ }
+
+ void reserve( size_type n ) // strong
+ {
+ BOOST_ASSERT( members_.capacity_ >= N );
+
+ if( n <= members_.capacity_ )
+ return;
+
+ reserve_impl( new_capacity_impl( n ) );
+ BOOST_ASSERT( members_.capacity_ >= n );
+ }
+
+ void push_back()
+ {
+ if( size_ != members_.capacity_ )
+ {
+ unchecked_push_back();
+ }
+ else
+ {
+ reserve( size_ + 1u );
+ unchecked_push_back();
+ }
+ }
+
+ void push_back( optimized_const_reference x )
+ {
+ if( size_ != members_.capacity_ )
+ {
+ unchecked_push_back( x );
+ }
+ else
+ {
+ reserve( size_ + 1u );
+ unchecked_push_back( x );
+ }
+ }
+
+ template< class ForwardIterator >
+ void push_back( ForwardIterator begin_arg, ForwardIterator end_arg )
+ {
+ difference_type diff = std::distance(begin_arg, end_arg);
+ if( size_ + diff > members_.capacity_ )
+ reserve( size_ + diff );
+ unchecked_push_back( begin_arg, end_arg );
+ }
+
+ iterator insert( const_iterator before, optimized_const_reference x ) // basic
+ {
+ // @todo: consider if we want to support x in 'this'
+ if( size_ < members_.capacity_ )
+ {
+ bool is_back_insertion = before == cend();
+ iterator where = const_cast<T*>(before);
+
+ if( !is_back_insertion )
+ {
+ grow_back_one();
+ std::copy( before, cend() - 1u, where + 1u );
+ *where = x;
+ BOOST_ASSERT( is_valid() );
+ }
+ else
+ {
+ unchecked_push_back( x );
+ }
+ return where;
+ }
+
+ auto_buffer temp( new_capacity_impl( size_ + 1u ) );
+ temp.unchecked_push_back( cbegin(), before );
+ iterator result = temp.end();
+ temp.unchecked_push_back( x );
+ temp.unchecked_push_back( before, cend() );
+ one_sided_swap( temp );
+ BOOST_ASSERT( is_valid() );
+ return result;
+ }
+
+ void insert( const_iterator before, size_type n,
+ optimized_const_reference x )
+ {
+ // @todo: see problems above
+ if( size_ + n <= members_.capacity_ )
+ {
+ grow_back( n );
+ iterator where = const_cast<T*>(before);
+ std::copy( before, cend() - n, where + n );
+ std::fill( where, where + n, x );
+ BOOST_ASSERT( is_valid() );
+ return;
+ }
+
+ auto_buffer temp( new_capacity_impl( size_ + n ) );
+ temp.unchecked_push_back( cbegin(), before );
+ std::uninitialized_fill_n( temp.end(), n, x );
+ temp.size_ += n;
+ temp.unchecked_push_back( before, cend() );
+ one_sided_swap( temp );
+ BOOST_ASSERT( is_valid() );
+ }
+
+ template< class ForwardIterator >
+ void insert( const_iterator before,
+ ForwardIterator begin_arg, ForwardIterator end_arg ) // basic
+ {
+ typedef typename std::iterator_traits<ForwardIterator>
+ ::iterator_category category;
+ insert_impl( before, begin_arg, end_arg, category() );
+ }
+
+ void pop_back()
+ {
+ BOOST_ASSERT( !empty() );
+ auto_buffer_destroy( buffer_ + size_ - 1, boost::has_trivial_destructor<T>() );
+ --size_;
+ }
+
+ void pop_back_n( size_type n )
+ {
+ BOOST_ASSERT( n <= size_ );
+ if( n )
+ {
+ destroy_back_n( n );
+ size_ -= n;
+ }
+ }
+
+ void clear()
+ {
+ pop_back_n( size_ );
+ }
+
+ iterator erase( const_iterator where )
+ {
+ BOOST_ASSERT( !empty() );
+ BOOST_ASSERT( cbegin() <= where );
+ BOOST_ASSERT( cend() > where );
+
+ unsigned elements = cend() - where - 1u;
+
+ if( elements > 0u )
+ {
+ const_iterator start = where + 1u;
+ std::copy( start, start + elements,
+ const_cast<T*>(where) );
+ }
+ pop_back();
+ BOOST_ASSERT( !full() );
+ iterator result = const_cast<T*>( where );
+ BOOST_ASSERT( result <= end() );
+ return result;
+ }
+
+ iterator erase( const_iterator from, const_iterator to )
+ {
+ BOOST_ASSERT( !(std::distance(from,to)>0) ||
+ !empty() );
+ BOOST_ASSERT( cbegin() <= from );
+ BOOST_ASSERT( cend() >= to );
+
+ unsigned elements = std::distance(to,cend());
+
+ if( elements > 0u )
+ {
+ BOOST_ASSERT( elements > 0u );
+ std::copy( to, to + elements,
+ const_cast<T*>(from) );
+ }
+ pop_back_n( std::distance(from,to) );
+ BOOST_ASSERT( !full() );
+ iterator result = const_cast<T*>( from );
+ BOOST_ASSERT( result <= end() );
+ return result;
+ }
+
+ void shrink_to_fit()
+ {
+ if( is_on_stack() || !GrowPolicy::should_shrink(size_,members_.capacity_) )
+ return;
+
+ reserve_impl( size_ );
+ members_.capacity_ = (std::max)(size_type(N),members_.capacity_);
+ BOOST_ASSERT( is_on_stack() || size_ == members_.capacity_ );
+ BOOST_ASSERT( !is_on_stack() || size_ <= members_.capacity_ );
+ }
+
+ pointer uninitialized_grow( size_type n ) // strong
+ {
+ if( size_ + n <= members_.capacity_ )
+ reserve( size_ + n );
+
+ pointer res = end();
+ size_ += n;
+ return res;
+ }
+
+ void uninitialized_shrink( size_type n ) // nothrow
+ {
+ // @remark: test for wrap-around
+ BOOST_ASSERT( size_ - n <= members_.capacity_ );
+ size_ -= n;
+ }
+
+ void uninitialized_resize( size_type n )
+ {
+ if( n > size() )
+ uninitialized_grow( n - size() );
+ else if( n < size() )
+ uninitialized_shrink( size() - n );
+
+ BOOST_ASSERT( size() == n );
+ }
+
+ // nothrow - if both buffer are on the heap, or
+ // - if one buffer is on the heap and one has
+ // 'has_allocated_buffer() == false', or
+ // - if copy-construction cannot throw
+ // basic - otherwise (better guarantee impossible)
+ // requirement: the allocator must be no-throw-swappable
+ void swap( auto_buffer& r )
+ {
+ bool on_stack = is_on_stack();
+ bool r_on_stack = r.is_on_stack();
+ bool both_on_heap = !on_stack && !r_on_stack;
+ if( both_on_heap )
+ {
+ boost::swap( get_allocator(), r.get_allocator() );
+ boost::swap( members_.capacity_, r.members_.capacity_ );
+ boost::swap( buffer_, r.buffer_ );
+ boost::swap( size_, r.size_ );
+ BOOST_ASSERT( is_valid() );
+ BOOST_ASSERT( r.is_valid() );
+ return;
+ }
+
+ BOOST_ASSERT( on_stack || r_on_stack );
+ bool exactly_one_on_stack = (on_stack && !r_on_stack) ||
+ (!on_stack && r_on_stack);
+
+ //
+ // Remark: we now know that we can copy into
+ // the unused stack buffer.
+ //
+ if( exactly_one_on_stack )
+ {
+ auto_buffer* one_on_stack = on_stack ? this : &r;
+ auto_buffer* other = on_stack ? &r : this;
+ pointer new_buffer = static_cast<T*>(other->members_.address());
+ copy_impl( one_on_stack->begin(), one_on_stack->end(),
+ new_buffer ); // strong
+ one_on_stack->~auto_buffer(); // nothrow
+ boost::swap( get_allocator(), r.get_allocator() ); // assume nothrow
+ boost::swap( members_.capacity_, r.members_.capacity_ );
+ boost::swap( size_, r.size_ );
+ one_on_stack->buffer_ = other->buffer_;
+ other->buffer_ = new_buffer;
+ BOOST_ASSERT( other->is_on_stack() );
+ BOOST_ASSERT( !one_on_stack->is_on_stack() );
+ BOOST_ASSERT( is_valid() );
+ BOOST_ASSERT( r.is_valid() );
+ return;
+ }
+
+ BOOST_ASSERT( on_stack && r_on_stack );
+ swap_helper( *this, r, boost::has_trivial_assign<T>() );
+ BOOST_ASSERT( is_valid() );
+ BOOST_ASSERT( r.is_valid() );
+ }
+
+ private:
+ typedef boost::aligned_storage< N * sizeof(T),
+ boost::alignment_of<T>::value >
+ storage;
+
+ struct members_type : storage /* to enable EBO */
+ {
+ size_type capacity_;
+
+ members_type( size_type capacity )
+ : capacity_(capacity)
+ { }
+
+ void* address() const
+ { return const_cast<storage&>(static_cast<const storage&>(*this)).address(); }
+ };
+
+ members_type members_;
+ pointer buffer_;
+ size_type size_;
+
+ };
+
+ template< class T, class SBP, class GP, class A >
+ inline void swap( auto_buffer<T,SBP,GP,A>& l, auto_buffer<T,SBP,GP,A>& r )
+ {
+ l.swap( r );
+ }
+
+ template< class T, class SBP, class GP, class A >
+ inline bool operator==( const auto_buffer<T,SBP,GP,A>& l,
+ const auto_buffer<T,SBP,GP,A>& r )
+ {
+ if( l.size() != r.size() )
+ return false;
+ return std::equal( l.begin(), l.end(), r.begin() );
+ }
+
+ template< class T, class SBP, class GP, class A >
+ inline bool operator!=( const auto_buffer<T,SBP,GP,A>& l,
+ const auto_buffer<T,SBP,GP,A>& r )
+ {
+ return !(l == r);
+ }
+
+ template< class T, class SBP, class GP, class A >
+ inline bool operator<( const auto_buffer<T,SBP,GP,A>& l,
+ const auto_buffer<T,SBP,GP,A>& r )
+ {
+ return std::lexicographical_compare( l.begin(), l.end(),
+ r.begin(), r.end() );
+ }
+
+ template< class T, class SBP, class GP, class A >
+ inline bool operator>( const auto_buffer<T,SBP,GP,A>& l,
+ const auto_buffer<T,SBP,GP,A>& r )
+ {
+ return (r < l);
+ }
+
+ template< class T, class SBP, class GP, class A >
+ inline bool operator<=( const auto_buffer<T,SBP,GP,A>& l,
+ const auto_buffer<T,SBP,GP,A>& r )
+ {
+ return !(r > l);
+ }
+
+ template< class T, class SBP, class GP, class A >
+ inline bool operator>=( const auto_buffer<T,SBP,GP,A>& l,
+ const auto_buffer<T,SBP,GP,A>& r )
+ {
+ return !(l < r);
+ }
+
+} // namespace detail
+} // namespace signals2
+}
+
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+#pragma warning(pop)
+#endif
+
+#endif
diff --git a/3rdParty/Boost/src/boost/signals2/detail/foreign_ptr.hpp b/3rdParty/Boost/src/boost/signals2/detail/foreign_ptr.hpp
new file mode 100644
index 0000000..4349b38
--- /dev/null
+++ b/3rdParty/Boost/src/boost/signals2/detail/foreign_ptr.hpp
@@ -0,0 +1,185 @@
+
+// helper code for dealing with tracking non-boost shared_ptr/weak_ptr
+
+// Copyright Frank Mori Hess 2009.
+// Distributed under the 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/signals2 for library home page.
+
+#ifndef BOOST_SIGNALS2_FOREIGN_PTR_HPP
+#define BOOST_SIGNALS2_FOREIGN_PTR_HPP
+
+#include <algorithm>
+#include <boost/config.hpp>
+#include <boost/assert.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/smart_ptr/bad_weak_ptr.hpp>
+#include <boost/utility/swap.hpp>
+
+#ifndef BOOST_NO_CXX11_SMART_PTR
+#include <memory>
+#endif
+
+namespace boost
+{
+ template<typename T> class shared_ptr;
+ template<typename T> class weak_ptr;
+
+ namespace signals2
+ {
+ template<typename WeakPtr> struct weak_ptr_traits
+ {};
+ template<typename T> struct weak_ptr_traits<boost::weak_ptr<T> >
+ {
+ typedef boost::shared_ptr<T> shared_type;
+ };
+#ifndef BOOST_NO_CXX11_SMART_PTR
+ template<typename T> struct weak_ptr_traits<std::weak_ptr<T> >
+ {
+ typedef std::shared_ptr<T> shared_type;
+ };
+#endif
+
+ template<typename SharedPtr> struct shared_ptr_traits
+ {};
+
+ template<typename T> struct shared_ptr_traits<boost::shared_ptr<T> >
+ {
+ typedef boost::weak_ptr<T> weak_type;
+ };
+#ifndef BOOST_NO_CXX11_SMART_PTR
+ template<typename T> struct shared_ptr_traits<std::shared_ptr<T> >
+ {
+ typedef std::weak_ptr<T> weak_type;
+ };
+#endif
+
+ namespace detail
+ {
+ struct foreign_shared_ptr_impl_base
+ {
+ virtual ~foreign_shared_ptr_impl_base() {}
+ virtual void* get() const = 0;
+ virtual foreign_shared_ptr_impl_base * clone() const = 0;
+ };
+
+ template<typename FSP>
+ class foreign_shared_ptr_impl: public foreign_shared_ptr_impl_base
+ {
+ public:
+ foreign_shared_ptr_impl(const FSP &p): _p(p)
+ {}
+ virtual void * get() const
+ {
+ return _p.get();
+ }
+ virtual foreign_shared_ptr_impl * clone() const
+ {
+ return new foreign_shared_ptr_impl(*this);
+ }
+ private:
+ FSP _p;
+ };
+
+ class foreign_void_shared_ptr
+ {
+ public:
+ foreign_void_shared_ptr():
+ _p(0)
+ {}
+ foreign_void_shared_ptr(const foreign_void_shared_ptr &other):
+ _p(other._p->clone())
+ {}
+ template<typename FSP>
+ explicit foreign_void_shared_ptr(const FSP &fsp):
+ _p(new foreign_shared_ptr_impl<FSP>(fsp))
+ {}
+ ~foreign_void_shared_ptr()
+ {
+ delete _p;
+ }
+ foreign_void_shared_ptr & operator=(const foreign_void_shared_ptr &other)
+ {
+ if(&other == this) return *this;
+ foreign_void_shared_ptr(other).swap(*this);
+ return *this;
+ }
+ void swap(foreign_void_shared_ptr &other)
+ {
+ boost::swap(_p, other._p);
+ }
+ private:
+ foreign_shared_ptr_impl_base *_p;
+ };
+
+ struct foreign_weak_ptr_impl_base
+ {
+ virtual ~foreign_weak_ptr_impl_base() {}
+ virtual foreign_void_shared_ptr lock() const = 0;
+ virtual bool expired() const = 0;
+ virtual foreign_weak_ptr_impl_base * clone() const = 0;
+ };
+
+ template<typename FWP>
+ class foreign_weak_ptr_impl: public foreign_weak_ptr_impl_base
+ {
+ public:
+ foreign_weak_ptr_impl(const FWP &p): _p(p)
+ {}
+ virtual foreign_void_shared_ptr lock() const
+ {
+ return foreign_void_shared_ptr(_p.lock());
+ }
+ virtual bool expired() const
+ {
+ return _p.expired();
+ }
+ virtual foreign_weak_ptr_impl * clone() const
+ {
+ return new foreign_weak_ptr_impl(*this);
+ }
+ private:
+ FWP _p;
+ };
+
+ class foreign_void_weak_ptr
+ {
+ public:
+ foreign_void_weak_ptr()
+ {}
+ foreign_void_weak_ptr(const foreign_void_weak_ptr &other):
+ _p(other._p->clone())
+ {}
+ template<typename FWP>
+ explicit foreign_void_weak_ptr(const FWP &fwp):
+ _p(new foreign_weak_ptr_impl<FWP>(fwp))
+ {}
+ foreign_void_weak_ptr & operator=(const foreign_void_weak_ptr &other)
+ {
+ if(&other == this) return *this;
+ foreign_void_weak_ptr(other).swap(*this);
+ return *this;
+ }
+ void swap(foreign_void_weak_ptr &other)
+ {
+ boost::swap(_p, other._p);
+ }
+ foreign_void_shared_ptr lock() const
+ {
+ return _p->lock();
+ }
+ bool expired() const
+ {
+ return _p->expired();
+ }
+ private:
+ boost::scoped_ptr<foreign_weak_ptr_impl_base> _p;
+ };
+ } // namespace detail
+
+ } // namespace signals2
+} // namespace boost
+
+#endif // BOOST_SIGNALS2_FOREIGN_PTR_HPP
diff --git a/3rdParty/Boost/src/boost/signals2/detail/lwm_nop.hpp b/3rdParty/Boost/src/boost/signals2/detail/lwm_nop.hpp
new file mode 100644
index 0000000..2b70544
--- /dev/null
+++ b/3rdParty/Boost/src/boost/signals2/detail/lwm_nop.hpp
@@ -0,0 +1,38 @@
+//
+// boost/signals2/detail/lwm_nop.hpp
+//
+// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
+// Copyright (c) 2008 Frank Mori Hess
+//
+// Distributed under the 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_SIGNALS2_LWM_NOP_HPP
+#define BOOST_SIGNALS2_LWM_NOP_HPP
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+
+#include <boost/signals2/dummy_mutex.hpp>
+
+namespace boost
+{
+
+namespace signals2
+{
+
+class mutex: public dummy_mutex
+{
+};
+
+} // namespace signals2
+
+} // namespace boost
+
+#endif // #ifndef BOOST_SIGNALS2_LWM_NOP_HPP
diff --git a/3rdParty/Boost/src/boost/signals2/detail/lwm_pthreads.hpp b/3rdParty/Boost/src/boost/signals2/detail/lwm_pthreads.hpp
new file mode 100644
index 0000000..fb0dd66
--- /dev/null
+++ b/3rdParty/Boost/src/boost/signals2/detail/lwm_pthreads.hpp
@@ -0,0 +1,78 @@
+//
+// boost/signals2/detail/lwm_pthreads.hpp
+//
+// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
+// Copyright (c) 2008 Frank Mori Hess
+//
+// Distributed under the 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_SIGNALS2_LWM_PTHREADS_HPP
+#define BOOST_SIGNALS2_LWM_PTHREADS_HPP
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/assert.hpp>
+#include <pthread.h>
+
+namespace boost
+{
+
+namespace signals2
+{
+
+class mutex
+{
+private:
+
+ pthread_mutex_t m_;
+
+ mutex(mutex const &);
+ mutex & operator=(mutex const &);
+
+public:
+
+ mutex()
+ {
+
+// HPUX 10.20 / DCE has a nonstandard pthread_mutex_init
+
+#if defined(__hpux) && defined(_DECTHREADS_)
+ BOOST_VERIFY(pthread_mutex_init(&m_, pthread_mutexattr_default) == 0);
+#else
+ BOOST_VERIFY(pthread_mutex_init(&m_, 0) == 0);
+#endif
+ }
+
+ ~mutex()
+ {
+ BOOST_VERIFY(pthread_mutex_destroy(&m_) == 0);
+ }
+
+ void lock()
+ {
+ BOOST_VERIFY(pthread_mutex_lock(&m_) == 0);
+ }
+
+ bool try_lock()
+ {
+ return pthread_mutex_trylock(&m_) == 0;
+ }
+
+ void unlock()
+ {
+ BOOST_VERIFY(pthread_mutex_unlock(&m_) == 0);
+ }
+};
+
+} // namespace signals2
+
+} // namespace boost
+
+#endif // #ifndef BOOST_SIGNALS2_LWM_PTHREADS_HPP
diff --git a/3rdParty/Boost/src/boost/signals2/detail/lwm_win32_cs.hpp b/3rdParty/Boost/src/boost/signals2/detail/lwm_win32_cs.hpp
new file mode 100644
index 0000000..d1c1965
--- /dev/null
+++ b/3rdParty/Boost/src/boost/signals2/detail/lwm_win32_cs.hpp
@@ -0,0 +1,120 @@
+//
+// boost/signals2/detail/lwm_win32_cs.hpp
+//
+// Copyright (c) 2002, 2003 Peter Dimov
+// Copyright (c) 2008 Frank Mori Hess
+// Copyright (c) Microsoft Corporation 2014
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_SIGNALS2_LWM_WIN32_CS_HPP
+#define BOOST_SIGNALS2_LWM_WIN32_CS_HPP
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/assert.hpp>
+
+#ifdef BOOST_USE_WINDOWS_H
+# include <windows.h>
+#endif
+
+#include <boost/predef/platform.h>
+
+namespace boost
+{
+
+namespace signals2
+{
+
+#ifndef BOOST_USE_WINDOWS_H
+
+struct critical_section
+{
+ struct critical_section_debug * DebugInfo;
+ long LockCount;
+ long RecursionCount;
+ void * OwningThread;
+ void * LockSemaphore;
+#if defined(_WIN64)
+ unsigned __int64 SpinCount;
+#else
+ unsigned long SpinCount;
+#endif
+};
+
+#if BOOST_PLAT_WINDOWS_RUNTIME
+extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSectionEx(critical_section *, unsigned long, unsigned long);
+#else
+extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSection(critical_section *);
+#endif
+extern "C" __declspec(dllimport) void __stdcall EnterCriticalSection(critical_section *);
+extern "C" __declspec(dllimport) bool __stdcall TryEnterCriticalSection(critical_section *);
+extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(critical_section *);
+extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(critical_section *);
+
+#else
+
+typedef ::CRITICAL_SECTION critical_section;
+
+#endif // #ifndef BOOST_USE_WINDOWS_H
+
+class mutex
+{
+private:
+
+ critical_section cs_;
+
+ mutex(mutex const &);
+ mutex & operator=(mutex const &);
+
+public:
+
+ mutex()
+ {
+#if BOOST_PLAT_WINDOWS_RUNTIME
+ InitializeCriticalSectionEx(&cs_, 4000, 0);
+#else
+ InitializeCriticalSection(&cs_);
+#endif
+ }
+
+ ~mutex()
+ {
+ DeleteCriticalSection(&cs_);
+ }
+
+ void lock()
+ {
+ EnterCriticalSection(&cs_);
+ }
+// TryEnterCriticalSection only exists on Windows NT 4.0 and later
+#if (defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400))
+ bool try_lock()
+ {
+ return TryEnterCriticalSection(&cs_) != 0;
+ }
+#else
+ bool try_lock()
+ {
+ BOOST_ASSERT(false);
+ return false;
+ }
+#endif
+ void unlock()
+ {
+ LeaveCriticalSection(&cs_);
+ }
+};
+
+} // namespace signals2
+
+} // namespace boost
+
+#endif // #ifndef BOOST_SIGNALS2_LWM_WIN32_CS_HPP
diff --git a/3rdParty/Boost/src/boost/signals2/detail/null_output_iterator.hpp b/3rdParty/Boost/src/boost/signals2/detail/null_output_iterator.hpp
new file mode 100644
index 0000000..9e98695
--- /dev/null
+++ b/3rdParty/Boost/src/boost/signals2/detail/null_output_iterator.hpp
@@ -0,0 +1,34 @@
+/*
+ An output iterator which simply discards output.
+*/
+// Copyright Frank Mori Hess 2008.
+// Distributed under the 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/signals2 for library home page.
+
+#ifndef BOOST_SIGNALS2_NULL_OUTPUT_ITERATOR_HPP
+#define BOOST_SIGNALS2_NULL_OUTPUT_ITERATOR_HPP
+
+#include <boost/function_output_iterator.hpp>
+
+namespace boost
+{
+ namespace signals2
+ {
+ namespace detail
+ {
+ class does_nothing
+ {
+ public:
+ template<typename T>
+ void operator()(const T&) const
+ {}
+ };
+ typedef boost::function_output_iterator<does_nothing> null_output_iterator;
+ } // namespace detail
+ } // namespace signals2
+} // namespace boost
+
+#endif // BOOST_SIGNALS2_NULL_OUTPUT_ITERATOR_HPP
diff --git a/3rdParty/Boost/src/boost/signals2/detail/preprocessed_arg_type.hpp b/3rdParty/Boost/src/boost/signals2/detail/preprocessed_arg_type.hpp
new file mode 100644
index 0000000..02717c9
--- /dev/null
+++ b/3rdParty/Boost/src/boost/signals2/detail/preprocessed_arg_type.hpp
@@ -0,0 +1,34 @@
+// Boost.Signals2 library
+
+// Copyright Frank Mori Hess 2007-2009.
+// Copyright Timmo Stange 2007.
+// Copyright Douglas Gregor 2001-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#ifndef BOOST_SIGNALS2_PREPROCESSED_ARG_TYPE_HPP
+#define BOOST_SIGNALS2_PREPROCESSED_ARG_TYPE_HPP
+
+#include <boost/preprocessor/repetition.hpp>
+#include <boost/signals2/detail/signals_common_macros.hpp>
+
+#define BOOST_PP_ITERATION_LIMITS (0, BOOST_PP_INC(BOOST_SIGNALS2_MAX_ARGS))
+#define BOOST_PP_FILENAME_1 <boost/signals2/detail/preprocessed_arg_type_template.hpp>
+#include BOOST_PP_ITERATE()
+
+namespace boost
+{
+ namespace signals2
+ {
+ namespace detail
+ {
+ struct std_functional_base
+ {};
+ } // namespace detail
+ } // namespace signals2
+} // namespace boost
+
+#endif // BOOST_SIGNALS2_PREPROCESSED_ARG_TYPE_HPP
diff --git a/3rdParty/Boost/src/boost/signals2/detail/preprocessed_arg_type_template.hpp b/3rdParty/Boost/src/boost/signals2/detail/preprocessed_arg_type_template.hpp
new file mode 100644
index 0000000..4f39433
--- /dev/null
+++ b/3rdParty/Boost/src/boost/signals2/detail/preprocessed_arg_type_template.hpp
@@ -0,0 +1,39 @@
+// Copyright Frank Mori Hess 2009
+//
+// Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+// This file is included iteratively, and should not be protected from multiple inclusion
+
+#define BOOST_SIGNALS2_NUM_ARGS BOOST_PP_ITERATION()
+
+namespace boost
+{
+ namespace signals2
+ {
+ namespace detail
+ {
+ template<unsigned n BOOST_PP_COMMA_IF(BOOST_SIGNALS2_NUM_ARGS)
+ BOOST_SIGNALS2_ARGS_TEMPLATE_DECL(BOOST_SIGNALS2_NUM_ARGS)>
+ class BOOST_SIGNALS2_PREPROCESSED_ARG_N_TYPE_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS);
+
+// template<typename T1, typename T2, ... , typename TN> class preprocessed_arg_typeN<n, T1, T2, ..., TN>{...} ...
+#define BOOST_SIGNALS2_PREPROCESSED_ARG_TYPE_CLASS_TEMPLATE_SPECIALIZATION(z, n, data) \
+ template<BOOST_SIGNALS2_ARGS_TEMPLATE_DECL(BOOST_SIGNALS2_NUM_ARGS)> \
+ class BOOST_SIGNALS2_PREPROCESSED_ARG_N_TYPE_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)<n, \
+ BOOST_SIGNALS2_ARGS_TEMPLATE_INSTANTIATION(BOOST_SIGNALS2_NUM_ARGS)> \
+ { \
+ public: \
+ typedef BOOST_PP_CAT(T, BOOST_PP_INC(n)) type; \
+ };
+ BOOST_PP_REPEAT(BOOST_SIGNALS2_NUM_ARGS, BOOST_SIGNALS2_PREPROCESSED_ARG_TYPE_CLASS_TEMPLATE_SPECIALIZATION, ~)
+
+ } // namespace detail
+ } // namespace signals2
+} // namespace boost
+
+#undef BOOST_SIGNALS2_NUM_ARGS
diff --git a/3rdParty/Boost/src/boost/signals2/detail/replace_slot_function.hpp b/3rdParty/Boost/src/boost/signals2/detail/replace_slot_function.hpp
new file mode 100644
index 0000000..de8f425
--- /dev/null
+++ b/3rdParty/Boost/src/boost/signals2/detail/replace_slot_function.hpp
@@ -0,0 +1,32 @@
+// Copyright Frank Mori Hess 2007-2009
+//
+// Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#ifndef BOOST_SIGNALS2_DETAIL_REPLACE_SLOT_FUNCTION_HPP
+#define BOOST_SIGNALS2_DETAIL_REPLACE_SLOT_FUNCTION_HPP
+
+#include <boost/signals2/slot_base.hpp>
+
+namespace boost
+{
+ namespace signals2
+ {
+ namespace detail
+ {
+ template<typename ResultSlot, typename SlotIn, typename SlotFunction>
+ ResultSlot replace_slot_function(const SlotIn &slot_in, const SlotFunction &fun)
+ {
+ ResultSlot slot(fun);
+ slot.track(slot_in);
+ return slot;
+ }
+ } // namespace detail
+ } // namespace signals2
+} // namespace boost
+
+#endif // BOOST_SIGNALS2_DETAIL_REPLACE_SLOT_FUNCTION_HPP
diff --git a/3rdParty/Boost/src/boost/signals2/detail/result_type_wrapper.hpp b/3rdParty/Boost/src/boost/signals2/detail/result_type_wrapper.hpp
new file mode 100644
index 0000000..35dea7c
--- /dev/null
+++ b/3rdParty/Boost/src/boost/signals2/detail/result_type_wrapper.hpp
@@ -0,0 +1,72 @@
+// Boost.Signals2 library
+
+// Copyright Douglas Gregor 2001-2004.
+// Copyright Frank Mori Hess 2007. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#ifndef BOOST_SIGNALS2_RESULT_TYPE_WRAPPER_HPP
+#define BOOST_SIGNALS2_RESULT_TYPE_WRAPPER_HPP
+
+#include <boost/config.hpp>
+
+namespace boost {
+ namespace signals2 {
+ namespace detail {
+ // A placeholder for void on compilers that don't support void returns
+ struct void_type {};
+
+ // Replaces void with void_type
+ template<typename R>
+ struct nonvoid {
+ typedef R type;
+ };
+ template<>
+ struct nonvoid<void> {
+ typedef void_type type;
+ };
+
+ // Replaces void with void_type only if compiler doesn't support void returns
+ template<typename R>
+ struct result_type_wrapper {
+ typedef R type;
+ };
+#ifdef BOOST_NO_VOID_RETURNS
+ template<>
+ struct result_type_wrapper<void> {
+ typedef void_type type;
+ };
+#endif
+
+ // specialization deals with possible void return from combiners
+ template<typename R> class combiner_invoker
+ {
+ public:
+ typedef R result_type;
+ template<typename Combiner, typename InputIterator>
+ result_type operator()(Combiner &combiner,
+ InputIterator first, InputIterator last) const
+ {
+ return combiner(first, last);
+ }
+ };
+ template<> class combiner_invoker<void>
+ {
+ public:
+ typedef result_type_wrapper<void>::type result_type;
+ template<typename Combiner, typename InputIterator>
+ result_type operator()(Combiner &combiner,
+ InputIterator first, InputIterator last) const
+ {
+ combiner(first, last);
+ return result_type();
+ }
+ };
+ } // end namespace detail
+ } // end namespace signals2
+} // end namespace boost
+
+#endif // BOOST_SIGNALS2_RESULT_TYPE_WRAPPER_HPP
diff --git a/3rdParty/Boost/src/boost/signals2/detail/signal_template.hpp b/3rdParty/Boost/src/boost/signals2/detail/signal_template.hpp
new file mode 100644
index 0000000..bb5d3a4
--- /dev/null
+++ b/3rdParty/Boost/src/boost/signals2/detail/signal_template.hpp
@@ -0,0 +1,859 @@
+/*
+ Template for Signa1, Signal2, ... classes that support signals
+ with 1, 2, ... parameters
+
+ Begin: 2007-01-23
+*/
+// Copyright Frank Mori Hess 2007-2008
+//
+// Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is included iteratively, and should not be protected from multiple inclusion
+
+#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+#define BOOST_SIGNALS2_NUM_ARGS BOOST_PP_ITERATION()
+#else
+#define BOOST_SIGNALS2_NUM_ARGS 1
+#endif
+
+// R, T1, T2, ..., TN, Combiner, Group, GroupCompare, SlotFunction, ExtendedSlotFunction, Mutex
+#define BOOST_SIGNALS2_SIGNAL_TEMPLATE_INSTANTIATION \
+ BOOST_SIGNALS2_SIGNATURE_TEMPLATE_INSTANTIATION(BOOST_SIGNALS2_NUM_ARGS), \
+ Combiner, Group, GroupCompare, SlotFunction, ExtendedSlotFunction, Mutex
+
+namespace boost
+{
+ namespace signals2
+ {
+ namespace detail
+ {
+ // helper for bound_extended_slot_function that handles specialization for void return
+ template<typename R>
+ class BOOST_SIGNALS2_BOUND_EXTENDED_SLOT_FUNCTION_INVOKER_N(BOOST_SIGNALS2_NUM_ARGS)
+ {
+ public:
+ typedef R result_type;
+ template<typename ExtendedSlotFunction BOOST_SIGNALS2_PP_COMMA_IF(BOOST_SIGNALS2_NUM_ARGS)
+ BOOST_SIGNALS2_ARGS_TEMPLATE_DECL(BOOST_SIGNALS2_NUM_ARGS)>
+ result_type operator()(ExtendedSlotFunction &func, const connection &conn
+ BOOST_SIGNALS2_PP_COMMA_IF(BOOST_SIGNALS2_NUM_ARGS)
+ BOOST_SIGNALS2_FULL_REF_ARGS(BOOST_SIGNALS2_NUM_ARGS)) const
+ {
+ return func(conn BOOST_SIGNALS2_PP_COMMA_IF(BOOST_SIGNALS2_NUM_ARGS)
+ BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS));
+ }
+ };
+#ifdef BOOST_NO_VOID_RETURNS
+ template<>
+ class BOOST_SIGNALS2_BOUND_EXTENDED_SLOT_FUNCTION_INVOKER_N(BOOST_SIGNALS2_NUM_ARGS)<void>
+ {
+ public:
+ typedef result_type_wrapper<void>::type result_type;
+ template<typename ExtendedSlotFunction BOOST_SIGNALS2_PP_COMMA_IF(BOOST_SIGNALS2_NUM_ARGS)
+ BOOST_SIGNALS2_ARGS_TEMPLATE_DECL(BOOST_SIGNALS2_NUM_ARGS)>
+ result_type operator()(ExtendedSlotFunction &func, const connection &conn
+ BOOST_SIGNALS2_PP_COMMA_IF(BOOST_SIGNALS2_NUM_ARGS)
+ BOOST_SIGNALS2_FULL_REF_ARGS(BOOST_SIGNALS2_NUM_ARGS)) const
+ {
+ func(conn BOOST_SIGNALS2_PP_COMMA_IF(BOOST_SIGNALS2_NUM_ARGS)
+ BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS));
+ return result_type();
+ }
+ };
+#endif
+// wrapper around an signalN::extended_slot_function which binds the
+// connection argument so it looks like a normal
+// signalN::slot_function
+
+ template<typename ExtendedSlotFunction>
+ class BOOST_SIGNALS2_BOUND_EXTENDED_SLOT_FUNCTION_N(BOOST_SIGNALS2_NUM_ARGS)
+ {
+ public:
+ typedef typename result_type_wrapper<typename ExtendedSlotFunction::result_type>::type result_type;
+ BOOST_SIGNALS2_BOUND_EXTENDED_SLOT_FUNCTION_N(BOOST_SIGNALS2_NUM_ARGS)(const ExtendedSlotFunction &fun):
+ _fun(fun), _connection(new connection)
+ {}
+ void set_connection(const connection &conn)
+ {
+ *_connection = conn;
+ }
+
+#if BOOST_SIGNALS2_NUM_ARGS > 0
+ template<BOOST_SIGNALS2_ARGS_TEMPLATE_DECL(BOOST_SIGNALS2_NUM_ARGS)>
+#endif // BOOST_SIGNALS2_NUM_ARGS > 0
+ result_type operator()(BOOST_SIGNALS2_FULL_REF_ARGS(BOOST_SIGNALS2_NUM_ARGS))
+ {
+ return BOOST_SIGNALS2_BOUND_EXTENDED_SLOT_FUNCTION_INVOKER_N(BOOST_SIGNALS2_NUM_ARGS)
+ <typename ExtendedSlotFunction::result_type>()
+ (_fun, *_connection BOOST_SIGNALS2_PP_COMMA_IF(BOOST_SIGNALS2_NUM_ARGS)
+ BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS));
+ }
+ // const overload
+#if BOOST_SIGNALS2_NUM_ARGS > 0
+ template<BOOST_SIGNALS2_ARGS_TEMPLATE_DECL(BOOST_SIGNALS2_NUM_ARGS)>
+#endif // BOOST_SIGNALS2_NUM_ARGS > 0
+ result_type operator()(BOOST_SIGNALS2_FULL_REF_ARGS(BOOST_SIGNALS2_NUM_ARGS)) const
+ {
+ return BOOST_SIGNALS2_BOUND_EXTENDED_SLOT_FUNCTION_INVOKER_N(BOOST_SIGNALS2_NUM_ARGS)
+ <typename ExtendedSlotFunction::result_type>()
+ (_fun, *_connection BOOST_SIGNALS2_PP_COMMA_IF(BOOST_SIGNALS2_NUM_ARGS)
+ BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS));
+ }
+ template<typename T>
+ bool operator==(const T &other) const
+ {
+ return _fun == other;
+ }
+ private:
+ BOOST_SIGNALS2_BOUND_EXTENDED_SLOT_FUNCTION_N(BOOST_SIGNALS2_NUM_ARGS)()
+ {}
+
+ ExtendedSlotFunction _fun;
+ boost::shared_ptr<connection> _connection;
+ };
+
+ template<BOOST_SIGNALS2_SIGNAL_TEMPLATE_DECL(BOOST_SIGNALS2_NUM_ARGS)>
+ class BOOST_SIGNALS2_SIGNAL_IMPL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS);
+
+ template<BOOST_SIGNALS2_SIGNAL_TEMPLATE_SPECIALIZATION_DECL(BOOST_SIGNALS2_NUM_ARGS)>
+ class BOOST_SIGNALS2_SIGNAL_IMPL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS) BOOST_SIGNALS2_SIGNAL_TEMPLATE_SPECIALIZATION
+ {
+ public:
+ typedef SlotFunction slot_function_type;
+ // typedef slotN<Signature, SlotFunction> slot_type;
+ typedef BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)
+ <BOOST_SIGNALS2_SIGNATURE_TEMPLATE_INSTANTIATION(BOOST_SIGNALS2_NUM_ARGS),
+ slot_function_type> slot_type;
+ typedef ExtendedSlotFunction extended_slot_function_type;
+ // typedef slotN+1<R, const connection &, T1, T2, ..., TN, extended_slot_function_type> extended_slot_type;
+ typedef BOOST_SIGNALS2_EXTENDED_SLOT_TYPE(BOOST_SIGNALS2_NUM_ARGS) extended_slot_type;
+ typedef typename nonvoid<typename slot_function_type::result_type>::type nonvoid_slot_result_type;
+ private:
+#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+ class slot_invoker;
+#else // BOOST_NO_CXX11_VARIADIC_TEMPLATES
+ typedef variadic_slot_invoker<nonvoid_slot_result_type, Args...> slot_invoker;
+#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
+ typedef slot_call_iterator_cache<nonvoid_slot_result_type, slot_invoker> slot_call_iterator_cache_type;
+ typedef typename group_key<Group>::type group_key_type;
+ typedef shared_ptr<connection_body<group_key_type, slot_type, Mutex> > connection_body_type;
+ typedef grouped_list<Group, GroupCompare, connection_body_type> connection_list_type;
+ typedef BOOST_SIGNALS2_BOUND_EXTENDED_SLOT_FUNCTION_N(BOOST_SIGNALS2_NUM_ARGS)<extended_slot_function_type>
+ bound_extended_slot_function_type;
+ public:
+ typedef Combiner combiner_type;
+ typedef typename result_type_wrapper<typename combiner_type::result_type>::type result_type;
+ typedef Group group_type;
+ typedef GroupCompare group_compare_type;
+ typedef typename detail::slot_call_iterator_t<slot_invoker,
+ typename connection_list_type::iterator, connection_body<group_key_type, slot_type, Mutex> > slot_call_iterator;
+
+ BOOST_SIGNALS2_SIGNAL_IMPL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)(const combiner_type &combiner_arg,
+ const group_compare_type &group_compare):
+ _shared_state(new invocation_state(connection_list_type(group_compare), combiner_arg)),
+ _garbage_collector_it(_shared_state->connection_bodies().end())
+ {}
+ // connect slot
+ connection connect(const slot_type &slot, connect_position position = at_back)
+ {
+ unique_lock<mutex_type> lock(_mutex);
+ return nolock_connect(slot, position);
+ }
+ connection connect(const group_type &group,
+ const slot_type &slot, connect_position position = at_back)
+ {
+ unique_lock<Mutex> lock(_mutex);
+ return nolock_connect(group, slot, position);
+ }
+ // connect extended slot
+ connection connect_extended(const extended_slot_type &ext_slot, connect_position position = at_back)
+ {
+ unique_lock<mutex_type> lock(_mutex);
+ bound_extended_slot_function_type bound_slot(ext_slot.slot_function());
+ slot_type slot = replace_slot_function<slot_type>(ext_slot, bound_slot);
+ connection conn = nolock_connect(slot, position);
+ bound_slot.set_connection(conn);
+ return conn;
+ }
+ connection connect_extended(const group_type &group,
+ const extended_slot_type &ext_slot, connect_position position = at_back)
+ {
+ unique_lock<Mutex> lock(_mutex);
+ bound_extended_slot_function_type bound_slot(ext_slot.slot_function());
+ slot_type slot = replace_slot_function<slot_type>(ext_slot, bound_slot);
+ connection conn = nolock_connect(group, slot, position);
+ bound_slot.set_connection(conn);
+ return conn;
+ }
+ // disconnect slot(s)
+ void disconnect_all_slots()
+ {
+ shared_ptr<invocation_state> local_state =
+ get_readable_state();
+ typename connection_list_type::iterator it;
+ for(it = local_state->connection_bodies().begin();
+ it != local_state->connection_bodies().end(); ++it)
+ {
+ (*it)->disconnect();
+ }
+ }
+ void disconnect(const group_type &group)
+ {
+ shared_ptr<invocation_state> local_state =
+ get_readable_state();
+ group_key_type group_key(grouped_slots, group);
+ typename connection_list_type::iterator it;
+ typename connection_list_type::iterator end_it =
+ local_state->connection_bodies().upper_bound(group_key);
+ for(it = local_state->connection_bodies().lower_bound(group_key);
+ it != end_it; ++it)
+ {
+ (*it)->disconnect();
+ }
+ }
+ template <typename T>
+ void disconnect(const T &slot)
+ {
+ typedef mpl::bool_<(is_convertible<T, group_type>::value)> is_group;
+ do_disconnect(slot, is_group());
+ }
+ // emit signal
+ result_type operator ()(BOOST_SIGNALS2_SIGNATURE_FULL_ARGS(BOOST_SIGNALS2_NUM_ARGS))
+ {
+ shared_ptr<invocation_state> local_state;
+ typename connection_list_type::iterator it;
+ {
+ unique_lock<mutex_type> list_lock(_mutex);
+ // only clean up if it is safe to do so
+ if(_shared_state.unique())
+ nolock_cleanup_connections(false, 1);
+ /* Make a local copy of _shared_state while holding mutex, so we are
+ thread safe against the combiner or connection list getting modified
+ during invocation. */
+ local_state = _shared_state;
+ }
+ slot_invoker invoker = slot_invoker(BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS));
+ slot_call_iterator_cache_type cache(invoker);
+ invocation_janitor janitor(cache, *this, &local_state->connection_bodies());
+ return detail::combiner_invoker<typename combiner_type::result_type>()
+ (
+ local_state->combiner(),
+ slot_call_iterator(local_state->connection_bodies().begin(), local_state->connection_bodies().end(), cache),
+ slot_call_iterator(local_state->connection_bodies().end(), local_state->connection_bodies().end(), cache)
+ );
+ }
+ result_type operator ()(BOOST_SIGNALS2_SIGNATURE_FULL_ARGS(BOOST_SIGNALS2_NUM_ARGS)) const
+ {
+ shared_ptr<invocation_state> local_state;
+ typename connection_list_type::iterator it;
+ {
+ unique_lock<mutex_type> list_lock(_mutex);
+ // only clean up if it is safe to do so
+ if(_shared_state.unique())
+ nolock_cleanup_connections(false, 1);
+ /* Make a local copy of _shared_state while holding mutex, so we are
+ thread safe against the combiner or connection list getting modified
+ during invocation. */
+ local_state = _shared_state;
+ }
+ slot_invoker invoker = slot_invoker(BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS));
+ slot_call_iterator_cache_type cache(invoker);
+ invocation_janitor janitor(cache, *this, &local_state->connection_bodies());
+ return detail::combiner_invoker<typename combiner_type::result_type>()
+ (
+ local_state->combiner(),
+ slot_call_iterator(local_state->connection_bodies().begin(), local_state->connection_bodies().end(), cache),
+ slot_call_iterator(local_state->connection_bodies().end(), local_state->connection_bodies().end(), cache)
+ );
+ }
+ std::size_t num_slots() const
+ {
+ shared_ptr<invocation_state> local_state =
+ get_readable_state();
+ typename connection_list_type::iterator it;
+ std::size_t count = 0;
+ for(it = local_state->connection_bodies().begin();
+ it != local_state->connection_bodies().end(); ++it)
+ {
+ if((*it)->connected()) ++count;
+ }
+ return count;
+ }
+ bool empty() const
+ {
+ shared_ptr<invocation_state> local_state =
+ get_readable_state();
+ typename connection_list_type::iterator it;
+ for(it = local_state->connection_bodies().begin();
+ it != local_state->connection_bodies().end(); ++it)
+ {
+ if((*it)->connected()) return false;
+ }
+ return true;
+ }
+ combiner_type combiner() const
+ {
+ unique_lock<mutex_type> lock(_mutex);
+ return _shared_state->combiner();
+ }
+ void set_combiner(const combiner_type &combiner_arg)
+ {
+ unique_lock<mutex_type> lock(_mutex);
+ if(_shared_state.unique())
+ _shared_state->combiner() = combiner_arg;
+ else
+ _shared_state.reset(new invocation_state(*_shared_state, combiner_arg));
+ }
+ private:
+ typedef Mutex mutex_type;
+
+ // slot_invoker is passed to slot_call_iterator_t to run slots
+#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+ class slot_invoker
+ {
+ public:
+ typedef nonvoid_slot_result_type result_type;
+// typename add_reference<Tn>::type
+#define BOOST_SIGNALS2_ADD_REF_TYPE(z, n, data) \
+ typename add_reference<BOOST_PP_CAT(T, BOOST_PP_INC(n))>::type
+// typename add_reference<Tn>::type argn
+#define BOOST_SIGNALS2_ADD_REF_ARG(z, n, data) \
+ BOOST_SIGNALS2_ADD_REF_TYPE(~, n, ~) \
+ BOOST_SIGNALS2_SIGNATURE_ARG_NAME(~, n, ~)
+// typename add_reference<T1>::type arg1, typename add_reference<T2>::type arg2, ..., typename add_reference<Tn>::type argn
+#define BOOST_SIGNALS2_ADD_REF_ARGS(arity) \
+ BOOST_PP_ENUM(arity, BOOST_SIGNALS2_ADD_REF_ARG, ~)
+ slot_invoker(BOOST_SIGNALS2_ADD_REF_ARGS(BOOST_SIGNALS2_NUM_ARGS)) BOOST_PP_EXPR_IF(BOOST_SIGNALS2_NUM_ARGS, :)
+#undef BOOST_SIGNALS2_ADD_REF_ARGS
+
+// m_argn
+#define BOOST_SIGNALS2_M_ARG_NAME(z, n, data) BOOST_PP_CAT(m_arg, BOOST_PP_INC(n))
+// m_argn ( argn )
+#define BOOST_SIGNALS2_MISC_STATEMENT(z, n, data) \
+ BOOST_SIGNALS2_M_ARG_NAME(~, n, ~) ( BOOST_SIGNALS2_SIGNATURE_ARG_NAME(~, n, ~) )
+// m_arg1(arg1), m_arg2(arg2), ..., m_argn(argn)
+ BOOST_PP_ENUM(BOOST_SIGNALS2_NUM_ARGS, BOOST_SIGNALS2_MISC_STATEMENT, ~)
+#undef BOOST_SIGNALS2_MISC_STATEMENT
+ {}
+ result_type operator ()(const connection_body_type &connectionBody) const
+ {
+ result_type *resolver = 0;
+ return m_invoke(connectionBody,
+ resolver);
+ }
+ private:
+ // declare assignment operator private since this class might have reference or const members
+ slot_invoker & operator=(const slot_invoker &);
+
+#define BOOST_SIGNALS2_ADD_REF_M_ARG_STATEMENT(z, n, data) \
+ BOOST_SIGNALS2_ADD_REF_TYPE(~, n, ~) BOOST_SIGNALS2_M_ARG_NAME(~, n, ~) ;
+ BOOST_PP_REPEAT(BOOST_SIGNALS2_NUM_ARGS, BOOST_SIGNALS2_ADD_REF_M_ARG_STATEMENT, ~)
+#undef BOOST_SIGNALS2_ADD_REF_M_ARG_STATEMENT
+#undef BOOST_SIGNALS2_ADD_REF_ARG
+#undef BOOST_SIGNALS2_ADD_REF_TYPE
+
+// m_arg1, m_arg2, ..., m_argn
+#define BOOST_SIGNALS2_M_ARG_NAMES(arity) BOOST_PP_ENUM(arity, BOOST_SIGNALS2_M_ARG_NAME, ~)
+ result_type m_invoke(const connection_body_type &connectionBody,
+ const void_type *) const
+ {
+ connectionBody->slot.slot_function()(BOOST_SIGNALS2_M_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS));
+ return void_type();
+ }
+ result_type m_invoke(const connection_body_type &connectionBody, ...) const
+ {
+ return connectionBody->slot.slot_function()(BOOST_SIGNALS2_M_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS));
+ }
+ };
+#undef BOOST_SIGNALS2_M_ARG_NAMES
+#undef BOOST_SIGNALS2_M_ARG_NAME
+
+#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
+ // a struct used to optimize (minimize) the number of shared_ptrs that need to be created
+ // inside operator()
+ class invocation_state
+ {
+ public:
+ invocation_state(const connection_list_type &connections_in,
+ const combiner_type &combiner_in): _connection_bodies(new connection_list_type(connections_in)),
+ _combiner(new combiner_type(combiner_in))
+ {}
+ invocation_state(const invocation_state &other, const connection_list_type &connections_in):
+ _connection_bodies(new connection_list_type(connections_in)),
+ _combiner(other._combiner)
+ {}
+ invocation_state(const invocation_state &other, const combiner_type &combiner_in):
+ _connection_bodies(other._connection_bodies),
+ _combiner(new combiner_type(combiner_in))
+ {}
+ connection_list_type & connection_bodies() { return *_connection_bodies; }
+ const connection_list_type & connection_bodies() const { return *_connection_bodies; }
+ combiner_type & combiner() { return *_combiner; }
+ const combiner_type & combiner() const { return *_combiner; }
+ private:
+ invocation_state(const invocation_state &);
+
+ shared_ptr<connection_list_type> _connection_bodies;
+ shared_ptr<combiner_type> _combiner;
+ };
+ // Destructor of invocation_janitor does some cleanup when a signal invocation completes.
+ // Code can't be put directly in signal's operator() due to complications from void return types.
+ class invocation_janitor
+ {
+ public:
+ typedef BOOST_SIGNALS2_SIGNAL_IMPL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS) signal_type;
+ invocation_janitor
+ (
+ const slot_call_iterator_cache_type &cache,
+ const signal_type &sig,
+ const connection_list_type *connection_bodies
+ ):_cache(cache), _sig(sig), _connection_bodies(connection_bodies)
+ {}
+ ~invocation_janitor()
+ {
+ // force a full cleanup of disconnected slots if there are too many
+ if(_cache.disconnected_slot_count > _cache.connected_slot_count)
+ {
+ _sig.force_cleanup_connections(_connection_bodies);
+ }
+ }
+ private:
+ const slot_call_iterator_cache_type &_cache;
+ const signal_type &_sig;
+ const connection_list_type *_connection_bodies;
+ };
+
+ // clean up disconnected connections
+ void nolock_cleanup_connections_from(bool grab_tracked,
+ const typename connection_list_type::iterator &begin, unsigned count = 0) const
+ {
+ BOOST_ASSERT(_shared_state.unique());
+ typename connection_list_type::iterator it;
+ unsigned i;
+ for(it = begin, i = 0;
+ it != _shared_state->connection_bodies().end() && (count == 0 || i < count);
+ ++i)
+ {
+ bool connected;
+ {
+ unique_lock<connection_body_base> lock(**it);
+ if(grab_tracked)
+ (*it)->nolock_slot_expired();
+ connected = (*it)->nolock_nograb_connected();
+ }// scoped lock destructs here, safe to erase now
+ if(connected == false)
+ {
+ it = _shared_state->connection_bodies().erase((*it)->group_key(), it);
+ }else
+ {
+ ++it;
+ }
+ }
+ _garbage_collector_it = it;
+ }
+ // clean up a few connections in constant time
+ void nolock_cleanup_connections(bool grab_tracked, unsigned count) const
+ {
+ BOOST_ASSERT(_shared_state.unique());
+ typename connection_list_type::iterator begin;
+ if(_garbage_collector_it == _shared_state->connection_bodies().end())
+ {
+ begin = _shared_state->connection_bodies().begin();
+ }else
+ {
+ begin = _garbage_collector_it;
+ }
+ nolock_cleanup_connections_from(grab_tracked, begin, count);
+ }
+ /* Make a new copy of the slot list if it is currently being read somewhere else
+ */
+ void nolock_force_unique_connection_list()
+ {
+ if(_shared_state.unique() == false)
+ {
+ _shared_state.reset(new invocation_state(*_shared_state, _shared_state->connection_bodies()));
+ nolock_cleanup_connections_from(true, _shared_state->connection_bodies().begin());
+ }else
+ {
+ /* We need to try and check more than just 1 connection here to avoid corner
+ cases where certain repeated connect/disconnect patterns cause the slot
+ list to grow without limit. */
+ nolock_cleanup_connections(true, 2);
+ }
+ }
+ // force a full cleanup of the connection list
+ void force_cleanup_connections(const connection_list_type *connection_bodies) const
+ {
+ unique_lock<mutex_type> list_lock(_mutex);
+ // if the connection list passed in as a parameter is no longer in use,
+ // we don't need to do any cleanup.
+ if(&_shared_state->connection_bodies() != connection_bodies)
+ {
+ return;
+ }
+ if(_shared_state.unique() == false)
+ {
+ _shared_state.reset(new invocation_state(*_shared_state, _shared_state->connection_bodies()));
+ }
+ nolock_cleanup_connections_from(false, _shared_state->connection_bodies().begin());
+ }
+ shared_ptr<invocation_state> get_readable_state() const
+ {
+ unique_lock<mutex_type> list_lock(_mutex);
+ return _shared_state;
+ }
+ connection_body_type create_new_connection(const slot_type &slot)
+ {
+ nolock_force_unique_connection_list();
+ return connection_body_type(new connection_body<group_key_type, slot_type, Mutex>(slot));
+ }
+ void do_disconnect(const group_type &group, mpl::bool_<true> /* is_group */)
+ {
+ disconnect(group);
+ }
+ template<typename T>
+ void do_disconnect(const T &slot, mpl::bool_<false> /* is_group */)
+ {
+ shared_ptr<invocation_state> local_state =
+ get_readable_state();
+ typename connection_list_type::iterator it;
+ for(it = local_state->connection_bodies().begin();
+ it != local_state->connection_bodies().end(); ++it)
+ {
+ unique_lock<connection_body_base> lock(**it);
+ if((*it)->slot.slot_function() == slot)
+ {
+ (*it)->nolock_disconnect();
+ }else
+ {
+ // check for wrapped extended slot
+ bound_extended_slot_function_type *fp;
+ fp = (*it)->slot.slot_function().template target<bound_extended_slot_function_type>();
+ if(fp && *fp == slot)
+ {
+ (*it)->nolock_disconnect();
+ }
+ }
+ }
+ }
+ // connect slot
+ connection nolock_connect(const slot_type &slot, connect_position position)
+ {
+ connection_body_type newConnectionBody =
+ create_new_connection(slot);
+ group_key_type group_key;
+ if(position == at_back)
+ {
+ group_key.first = back_ungrouped_slots;
+ _shared_state->connection_bodies().push_back(group_key, newConnectionBody);
+ }else
+ {
+ group_key.first = front_ungrouped_slots;
+ _shared_state->connection_bodies().push_front(group_key, newConnectionBody);
+ }
+ newConnectionBody->set_group_key(group_key);
+ return connection(newConnectionBody);
+ }
+ connection nolock_connect(const group_type &group,
+ const slot_type &slot, connect_position position)
+ {
+ connection_body_type newConnectionBody =
+ create_new_connection(slot);
+ // update map to first connection body in group if needed
+ group_key_type group_key(grouped_slots, group);
+ newConnectionBody->set_group_key(group_key);
+ if(position == at_back)
+ {
+ _shared_state->connection_bodies().push_back(group_key, newConnectionBody);
+ }else // at_front
+ {
+ _shared_state->connection_bodies().push_front(group_key, newConnectionBody);
+ }
+ return connection(newConnectionBody);
+ }
+
+ // _shared_state is mutable so we can do force_cleanup_connections during a const invocation
+ mutable shared_ptr<invocation_state> _shared_state;
+ mutable typename connection_list_type::iterator _garbage_collector_it;
+ // connection list mutex must never be locked when attempting a blocking lock on a slot,
+ // or you could deadlock.
+ mutable mutex_type _mutex;
+ };
+
+ template<BOOST_SIGNALS2_SIGNAL_TEMPLATE_DECL(BOOST_SIGNALS2_NUM_ARGS)>
+ class BOOST_SIGNALS2_WEAK_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS);
+ }
+
+ template<BOOST_SIGNALS2_SIGNAL_TEMPLATE_DEFAULTED_DECL(BOOST_SIGNALS2_NUM_ARGS)>
+ class BOOST_SIGNALS2_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS);
+
+ template<BOOST_SIGNALS2_SIGNAL_TEMPLATE_SPECIALIZATION_DECL(BOOST_SIGNALS2_NUM_ARGS)>
+ class BOOST_SIGNALS2_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)
+ BOOST_SIGNALS2_SIGNAL_TEMPLATE_SPECIALIZATION: public signal_base,
+ public detail::BOOST_SIGNALS2_STD_FUNCTIONAL_BASE
+ (typename detail::result_type_wrapper<typename Combiner::result_type>::type)
+ {
+ typedef detail::BOOST_SIGNALS2_SIGNAL_IMPL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)
+ <BOOST_SIGNALS2_SIGNAL_TEMPLATE_INSTANTIATION> impl_class;
+ public:
+ typedef detail::BOOST_SIGNALS2_WEAK_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)
+ <BOOST_SIGNALS2_SIGNAL_TEMPLATE_INSTANTIATION> weak_signal_type;
+ friend class detail::BOOST_SIGNALS2_WEAK_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)
+ <BOOST_SIGNALS2_SIGNAL_TEMPLATE_INSTANTIATION>;
+
+ typedef SlotFunction slot_function_type;
+ // typedef slotN<Signature, SlotFunction> slot_type;
+ typedef typename impl_class::slot_type slot_type;
+ typedef typename impl_class::extended_slot_function_type extended_slot_function_type;
+ typedef typename impl_class::extended_slot_type extended_slot_type;
+ typedef typename slot_function_type::result_type slot_result_type;
+ typedef Combiner combiner_type;
+ typedef typename impl_class::result_type result_type;
+ typedef Group group_type;
+ typedef GroupCompare group_compare_type;
+ typedef typename impl_class::slot_call_iterator
+ slot_call_iterator;
+ typedef typename mpl::identity<BOOST_SIGNALS2_SIGNATURE_FUNCTION_TYPE(BOOST_SIGNALS2_NUM_ARGS)>::type signature_type;
+
+#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+
+// typedef Tn argn_type;
+#define BOOST_SIGNALS2_MISC_STATEMENT(z, n, data) \
+ typedef BOOST_PP_CAT(T, BOOST_PP_INC(n)) BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(n)), _type);
+ BOOST_PP_REPEAT(BOOST_SIGNALS2_NUM_ARGS, BOOST_SIGNALS2_MISC_STATEMENT, ~)
+#undef BOOST_SIGNALS2_MISC_STATEMENT
+#if BOOST_SIGNALS2_NUM_ARGS == 1
+ typedef arg1_type argument_type;
+#elif BOOST_SIGNALS2_NUM_ARGS == 2
+ typedef arg1_type first_argument_type;
+ typedef arg2_type second_argument_type;
+#endif
+
+ template<unsigned n> class arg : public
+ detail::BOOST_SIGNALS2_PREPROCESSED_ARG_N_TYPE_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)
+ <n BOOST_SIGNALS2_PP_COMMA_IF(BOOST_SIGNALS2_NUM_ARGS)
+ BOOST_SIGNALS2_ARGS_TEMPLATE_INSTANTIATION(BOOST_SIGNALS2_NUM_ARGS)>
+ {};
+
+ BOOST_STATIC_CONSTANT(int, arity = BOOST_SIGNALS2_NUM_ARGS);
+
+#else // BOOST_NO_CXX11_VARIADIC_TEMPLATES
+
+ template<unsigned n> class arg
+ {
+ public:
+ typedef typename detail::variadic_arg_type<n, Args...>::type type;
+ };
+ BOOST_STATIC_CONSTANT(int, arity = sizeof...(Args));
+
+#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
+
+ BOOST_SIGNALS2_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)(const combiner_type &combiner_arg = combiner_type(),
+ const group_compare_type &group_compare = group_compare_type()):
+ _pimpl(new impl_class(combiner_arg, group_compare))
+ {};
+ virtual ~BOOST_SIGNALS2_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)()
+ {
+ }
+
+ //move support
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ BOOST_SIGNALS2_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)(
+ BOOST_SIGNALS2_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS) && other)
+ {
+ using std::swap;
+ swap(_pimpl, other._pimpl);
+ };
+
+ BOOST_SIGNALS2_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS) &
+ operator=(BOOST_SIGNALS2_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS) && rhs)
+ {
+ if(this == &rhs)
+ {
+ return *this;
+ }
+ _pimpl.reset();
+ using std::swap;
+ swap(_pimpl, rhs._pimpl);
+ return *this;
+ }
+#endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+
+ connection connect(const slot_type &slot, connect_position position = at_back)
+ {
+ return (*_pimpl).connect(slot, position);
+ }
+ connection connect(const group_type &group,
+ const slot_type &slot, connect_position position = at_back)
+ {
+ return (*_pimpl).connect(group, slot, position);
+ }
+ connection connect_extended(const extended_slot_type &slot, connect_position position = at_back)
+ {
+ return (*_pimpl).connect_extended(slot, position);
+ }
+ connection connect_extended(const group_type &group,
+ const extended_slot_type &slot, connect_position position = at_back)
+ {
+ return (*_pimpl).connect_extended(group, slot, position);
+ }
+ void disconnect_all_slots()
+ {
+ (*_pimpl).disconnect_all_slots();
+ }
+ void disconnect(const group_type &group)
+ {
+ (*_pimpl).disconnect(group);
+ }
+ template <typename T>
+ void disconnect(const T &slot)
+ {
+ (*_pimpl).disconnect(slot);
+ }
+ result_type operator ()(BOOST_SIGNALS2_SIGNATURE_FULL_ARGS(BOOST_SIGNALS2_NUM_ARGS))
+ {
+ return (*_pimpl)(BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS));
+ }
+ result_type operator ()(BOOST_SIGNALS2_SIGNATURE_FULL_ARGS(BOOST_SIGNALS2_NUM_ARGS)) const
+ {
+ return (*_pimpl)(BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS));
+ }
+ std::size_t num_slots() const
+ {
+ return (*_pimpl).num_slots();
+ }
+ bool empty() const
+ {
+ return (*_pimpl).empty();
+ }
+ combiner_type combiner() const
+ {
+ return (*_pimpl).combiner();
+ }
+ void set_combiner(const combiner_type &combiner_arg)
+ {
+ return (*_pimpl).set_combiner(combiner_arg);
+ }
+ void swap(BOOST_SIGNALS2_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS) & other)
+ {
+ using std::swap;
+ swap(_pimpl, other._pimpl);
+ }
+ protected:
+ virtual shared_ptr<void> lock_pimpl() const
+ {
+ return _pimpl;
+ }
+ private:
+ shared_ptr<impl_class>
+ _pimpl;
+ };
+
+#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+ // free swap function for signalN classes, findable by ADL
+ template<BOOST_SIGNALS2_SIGNAL_TEMPLATE_DECL(BOOST_SIGNALS2_NUM_ARGS)>
+ void swap(
+ BOOST_SIGNALS2_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS) <BOOST_SIGNALS2_SIGNAL_TEMPLATE_INSTANTIATION> &sig1,
+ BOOST_SIGNALS2_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS) <BOOST_SIGNALS2_SIGNAL_TEMPLATE_INSTANTIATION> &sig2 )
+ {
+ sig1.swap(sig2);
+ }
+#endif
+
+ namespace detail
+ {
+ // wrapper class for storing other signals as slots with automatic lifetime tracking
+ template<BOOST_SIGNALS2_SIGNAL_TEMPLATE_DECL(BOOST_SIGNALS2_NUM_ARGS)>
+ class BOOST_SIGNALS2_WEAK_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS);
+
+ template<BOOST_SIGNALS2_SIGNAL_TEMPLATE_SPECIALIZATION_DECL(BOOST_SIGNALS2_NUM_ARGS)>
+ class BOOST_SIGNALS2_WEAK_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)
+ BOOST_SIGNALS2_SIGNAL_TEMPLATE_SPECIALIZATION
+ {
+ public:
+ typedef typename BOOST_SIGNALS2_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)
+ <BOOST_SIGNALS2_SIGNAL_TEMPLATE_INSTANTIATION>::result_type
+ result_type;
+
+ BOOST_SIGNALS2_WEAK_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)
+ (const BOOST_SIGNALS2_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)
+ <BOOST_SIGNALS2_SIGNAL_TEMPLATE_INSTANTIATION>
+ &signal):
+ _weak_pimpl(signal._pimpl)
+ {}
+ result_type operator ()(BOOST_SIGNALS2_SIGNATURE_FULL_ARGS(BOOST_SIGNALS2_NUM_ARGS))
+ {
+ shared_ptr<detail::BOOST_SIGNALS2_SIGNAL_IMPL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)
+ <BOOST_SIGNALS2_SIGNAL_TEMPLATE_INSTANTIATION> >
+ shared_pimpl(_weak_pimpl.lock());
+ if(shared_pimpl == 0) boost::throw_exception(expired_slot());
+ return (*shared_pimpl)(BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS));
+ }
+ result_type operator ()(BOOST_SIGNALS2_SIGNATURE_FULL_ARGS(BOOST_SIGNALS2_NUM_ARGS)) const
+ {
+ shared_ptr<detail::BOOST_SIGNALS2_SIGNAL_IMPL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)
+ <BOOST_SIGNALS2_SIGNAL_TEMPLATE_INSTANTIATION> >
+ shared_pimpl(_weak_pimpl.lock());
+ if(shared_pimpl == 0) boost::throw_exception(expired_slot());
+ return (*shared_pimpl)(BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS));
+ }
+ private:
+ boost::weak_ptr<detail::BOOST_SIGNALS2_SIGNAL_IMPL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)
+ <BOOST_SIGNALS2_SIGNAL_TEMPLATE_INSTANTIATION> > _weak_pimpl;
+ };
+
+#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+ template<int arity, typename Signature>
+ class extended_signature: public variadic_extended_signature<Signature>
+ {};
+#else // BOOST_NO_CXX11_VARIADIC_TEMPLATES
+ template<int arity, typename Signature>
+ class extended_signature;
+ // partial template specialization
+ template<typename Signature>
+ class extended_signature<BOOST_SIGNALS2_NUM_ARGS, Signature>
+ {
+ public:
+// typename function_traits<Signature>::result_type (
+// const boost::signals2::connection &,
+// typename function_traits<Signature>::arg1_type,
+// typename function_traits<Signature>::arg2_type,
+// ...,
+// typename function_traits<Signature>::argn_type)
+#define BOOST_SIGNALS2_EXT_SIGNATURE(arity, Signature) \
+ typename function_traits<Signature>::result_type ( \
+ const boost::signals2::connection & BOOST_SIGNALS2_PP_COMMA_IF(BOOST_SIGNALS2_NUM_ARGS) \
+ BOOST_PP_ENUM(arity, BOOST_SIGNALS2_SIGNATURE_TO_ARGN_TYPE, Signature) )
+ typedef function<BOOST_SIGNALS2_EXT_SIGNATURE(BOOST_SIGNALS2_NUM_ARGS, Signature)> function_type;
+#undef BOOST_SIGNALS2_EXT_SIGNATURE
+ };
+
+ template<unsigned arity, typename Signature, typename Combiner,
+ typename Group, typename GroupCompare, typename SlotFunction,
+ typename ExtendedSlotFunction, typename Mutex>
+ class signalN;
+ // partial template specialization
+ template<typename Signature, typename Combiner, typename Group,
+ typename GroupCompare, typename SlotFunction,
+ typename ExtendedSlotFunction, typename Mutex>
+ class signalN<BOOST_SIGNALS2_NUM_ARGS, Signature, Combiner, Group,
+ GroupCompare, SlotFunction, ExtendedSlotFunction, Mutex>
+ {
+ public:
+ typedef BOOST_SIGNALS2_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)<
+ BOOST_SIGNALS2_PORTABLE_SIGNATURE(BOOST_SIGNALS2_NUM_ARGS, Signature),
+ Combiner, Group,
+ GroupCompare, SlotFunction, ExtendedSlotFunction, Mutex> type;
+ };
+
+#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
+
+ } // namespace detail
+ } // namespace signals2
+} // namespace boost
+
+#undef BOOST_SIGNALS2_NUM_ARGS
+#undef BOOST_SIGNALS2_SIGNAL_TEMPLATE_INSTANTIATION
diff --git a/3rdParty/Boost/src/boost/signals2/detail/signals_common.hpp b/3rdParty/Boost/src/boost/signals2/detail/signals_common.hpp
new file mode 100644
index 0000000..8c4baf0
--- /dev/null
+++ b/3rdParty/Boost/src/boost/signals2/detail/signals_common.hpp
@@ -0,0 +1,77 @@
+// Boost.Signals library
+
+// Copyright Douglas Gregor 2001-2004.
+// Copyright Frank Mori Hess 2007. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#ifndef BOOST_SIGNALS2_SIGNALS_COMMON_HPP
+#define BOOST_SIGNALS2_SIGNALS_COMMON_HPP
+
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/ref.hpp>
+#include <boost/signals2/signal_base.hpp>
+#include <boost/type_traits/is_base_of.hpp>
+
+namespace boost {
+ namespace signals2 {
+ namespace detail {
+ // Determine if the given type T is a signal
+ template<typename T>
+ class is_signal: public mpl::bool_<is_base_of<signal_base, T>::value>
+ {};
+
+ // A slot can be a signal, a reference to a function object, or a
+ // function object.
+ struct signal_tag {};
+ struct reference_tag {};
+ struct value_tag {};
+
+ // Classify the given slot as a signal, a reference-to-slot, or a
+ // standard slot
+ template<typename S>
+ class get_slot_tag {
+ typedef typename mpl::if_<is_signal<S>,
+ signal_tag, value_tag>::type signal_or_value;
+ public:
+ typedef typename mpl::if_<is_reference_wrapper<S>,
+ reference_tag,
+ signal_or_value>::type type;
+ };
+
+ // Get the slot so that it can be copied
+ template<typename F>
+ typename F::weak_signal_type
+ get_invocable_slot(const F &signal, signal_tag)
+ { return typename F::weak_signal_type(signal); }
+
+ template<typename F>
+ const F&
+ get_invocable_slot(const F& f, reference_tag)
+ { return f; }
+
+ template<typename F>
+ const F&
+ get_invocable_slot(const F& f, value_tag)
+ { return f; }
+
+ // Determines the type of the slot - is it a signal, a reference to a
+ // slot or just a normal slot.
+ template<typename F>
+ typename get_slot_tag<F>::type
+ tag_type(const F&)
+ {
+ typedef typename get_slot_tag<F>::type
+ the_tag_type;
+ the_tag_type tag = the_tag_type();
+ return tag;
+ }
+ } // end namespace detail
+ } // end namespace signals2
+} // end namespace boost
+
+#endif // BOOST_SIGNALS2_SIGNALS_COMMON_HPP
diff --git a/3rdParty/Boost/src/boost/signals2/detail/signals_common_macros.hpp b/3rdParty/Boost/src/boost/signals2/detail/signals_common_macros.hpp
new file mode 100644
index 0000000..b149dbc
--- /dev/null
+++ b/3rdParty/Boost/src/boost/signals2/detail/signals_common_macros.hpp
@@ -0,0 +1,212 @@
+/*
+ Author: Frank Mori Hess <fmhess@users.sourceforge.net>
+ Begin: 2007-01-23
+*/
+// Copyright Frank Mori Hess 2007-2008
+// Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_SIGNALS2_SIGNALS_COMMON_MACROS_HPP
+#define BOOST_SIGNALS2_SIGNALS_COMMON_MACROS_HPP
+
+#include <boost/config.hpp>
+
+#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+
+#ifndef BOOST_SIGNALS2_MAX_ARGS
+#define BOOST_SIGNALS2_MAX_ARGS 9
+#endif
+
+// signaln
+#define BOOST_SIGNALS2_SIGNAL_CLASS_NAME(arity) BOOST_PP_CAT(signal, arity)
+// weak_signaln
+#define BOOST_SIGNALS2_WEAK_SIGNAL_CLASS_NAME(arity) BOOST_PP_CAT(weak_, BOOST_SIGNALS2_SIGNAL_CLASS_NAME(arity))
+// signaln_impl
+#define BOOST_SIGNALS2_SIGNAL_IMPL_CLASS_NAME(arity) BOOST_PP_CAT(BOOST_SIGNALS2_SIGNAL_CLASS_NAME(arity), _impl)
+// argn
+#define BOOST_SIGNALS2_SIGNATURE_ARG_NAME(z, n, data) BOOST_PP_CAT(arg, BOOST_PP_INC(n))
+// Tn argn
+#define BOOST_SIGNALS2_SIGNATURE_FULL_ARG(z, n, data) \
+ BOOST_PP_CAT(T, BOOST_PP_INC(n)) BOOST_SIGNALS2_SIGNATURE_ARG_NAME(~, n, ~)
+// T1 arg1, T2 arg2, ..., Tn argn
+#define BOOST_SIGNALS2_SIGNATURE_FULL_ARGS(arity) \
+ BOOST_PP_ENUM(arity, BOOST_SIGNALS2_SIGNATURE_FULL_ARG, ~)
+// arg1, arg2, ..., argn
+#define BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(arity) BOOST_PP_ENUM(arity, BOOST_SIGNALS2_SIGNATURE_ARG_NAME, ~)
+// T1, T2, ..., TN
+#define BOOST_SIGNALS2_ARGS_TEMPLATE_INSTANTIATION(arity) \
+ BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_INC(arity), T)
+// R (T1, T2, ..., TN)
+#define BOOST_SIGNALS2_SIGNATURE_FUNCTION_TYPE(arity) \
+ R ( BOOST_SIGNALS2_ARGS_TEMPLATE_INSTANTIATION(arity) )
+// typename prefixR, typename prefixT1, typename prefixT2, ..., typename prefixTN
+#define BOOST_SIGNALS2_PREFIXED_SIGNATURE_TEMPLATE_DECL(arity, prefix) \
+ typename BOOST_PP_CAT(prefix, R) BOOST_PP_COMMA_IF(arity) \
+ BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_INC(arity), typename BOOST_PP_CAT(prefix, T))
+// typename R, typename T1, typename T2, ..., typename TN
+#define BOOST_SIGNALS2_SIGNATURE_TEMPLATE_DECL(arity) \
+ typename R BOOST_PP_COMMA_IF(arity) \
+ BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_INC(arity), typename T)
+// typename prefixT1, typename prefixT2, ..., typename prefixTN
+#define BOOST_SIGNALS2_PREFIXED_ARGS_TEMPLATE_DECL(arity, prefix) \
+ BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_INC(arity), typename BOOST_PP_CAT(prefix, T))
+// typename T1, typename T2, ..., typename TN
+#define BOOST_SIGNALS2_ARGS_TEMPLATE_DECL(arity) \
+ BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_INC(arity), typename T)
+// prefixR, prefixT1, prefixT2, ..., prefixTN
+#define BOOST_SIGNALS2_PREFIXED_SIGNATURE_TEMPLATE_INSTANTIATION(arity, prefix) \
+ BOOST_PP_CAT(prefix, R) BOOST_PP_COMMA_IF(arity) BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_INC(arity), BOOST_PP_CAT(prefix, T))
+// R, T1, T2, ..., TN
+#define BOOST_SIGNALS2_SIGNATURE_TEMPLATE_INSTANTIATION(arity) \
+ R BOOST_PP_COMMA_IF(arity) BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_INC(arity), T)
+// boost::functionN<R, T1, T2, ..., TN>
+#define BOOST_SIGNALS2_FUNCTION_N_DECL(arity) BOOST_PP_CAT(boost::function, arity)<\
+ BOOST_SIGNALS2_SIGNATURE_TEMPLATE_INSTANTIATION(arity) >
+// R, const boost::signals2::connection&, T1, T2, ..., TN
+#define BOOST_SIGNALS2_EXT_SLOT_TEMPLATE_INSTANTIATION(arity) \
+ R, const boost::signals2::connection& BOOST_PP_COMMA_IF(arity) \
+ BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_INC(arity), T)
+// boost::functionN<R, const boost::signals2::connection &, T1, T2, ..., TN>
+#define BOOST_SIGNALS2_EXT_FUNCTION_N_DECL(arity) BOOST_PP_CAT(boost::function, BOOST_PP_INC(arity))<\
+ BOOST_SIGNALS2_EXT_SLOT_TEMPLATE_INSTANTIATION(arity) >
+// slotN
+#define BOOST_SIGNALS2_SLOT_CLASS_NAME(arity) BOOST_PP_CAT(slot, arity)
+// slotN+1<R, const connection &, T1, T2, ..., TN, extended_slot_function_type>
+#define BOOST_SIGNALS2_EXTENDED_SLOT_TYPE(arity) \
+ BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_PP_INC(arity))< \
+ BOOST_SIGNALS2_EXT_SLOT_TEMPLATE_INSTANTIATION(arity), \
+ extended_slot_function_type>
+// bound_extended_slot_functionN
+#define BOOST_SIGNALS2_BOUND_EXTENDED_SLOT_FUNCTION_N(arity) BOOST_PP_CAT(bound_extended_slot_function, arity)
+// bound_extended_slot_function_helperN
+#define BOOST_SIGNALS2_BOUND_EXTENDED_SLOT_FUNCTION_INVOKER_N(arity) BOOST_PP_CAT(bound_extended_slot_function_invoker, arity)
+// typename function_traits<Signature>::argn_type
+#define BOOST_SIGNALS2_SIGNATURE_TO_ARGN_TYPE(z, n, Signature) \
+ BOOST_PP_CAT(BOOST_PP_CAT(typename function_traits<Signature>::arg, BOOST_PP_INC(n)), _type)
+// typename function_traits<Signature>::result_type,
+// typename function_traits<Signature>::arg1_type,
+// typename function_traits<Signature>::arg2_type,
+// ...,
+// typename function_traits<Signature>::argn_type
+#define BOOST_SIGNALS2_PORTABLE_SIGNATURE(arity, Signature) \
+ typename function_traits<Signature>::result_type \
+ BOOST_PP_COMMA_IF(arity) BOOST_PP_ENUM(arity, BOOST_SIGNALS2_SIGNATURE_TO_ARGN_TYPE, Signature)
+// prefixTn & argn
+#define BOOST_SIGNALS2_PREFIXED_FULL_REF_ARG(z, n, prefix) \
+ BOOST_PP_CAT(BOOST_PP_CAT(prefix, T), BOOST_PP_INC(n)) & BOOST_SIGNALS2_SIGNATURE_ARG_NAME(~, n, ~)
+// prefixT1 & arg1, prefixT2 & arg2, ..., prefixTn & argn
+#define BOOST_SIGNALS2_PREFIXED_FULL_REF_ARGS(arity, prefix) \
+ BOOST_PP_ENUM(arity, BOOST_SIGNALS2_PREFIXED_FULL_REF_ARG, prefix)
+// Tn & argn
+#define BOOST_SIGNALS2_FULL_REF_ARG(z, n, data) \
+ BOOST_PP_CAT(T, BOOST_PP_INC(n)) & BOOST_SIGNALS2_SIGNATURE_ARG_NAME(~, n, ~)
+// T1 & arg1, T2 & arg2, ..., Tn & argn
+#define BOOST_SIGNALS2_FULL_REF_ARGS(arity) \
+ BOOST_PP_ENUM(arity, BOOST_SIGNALS2_FULL_REF_ARG, ~)
+// preprocessed_arg_typeN
+#define BOOST_SIGNALS2_PREPROCESSED_ARG_N_TYPE_CLASS_NAME(arity) BOOST_PP_CAT(preprocessed_arg_type, arity)
+
+// typename R, typename T1, typename T2, ..., typename TN, typename SlotFunction
+#define BOOST_SIGNALS2_SLOT_TEMPLATE_SPECIALIZATION_DECL(arity) \
+ BOOST_SIGNALS2_SIGNATURE_TEMPLATE_DECL(arity), \
+ typename SlotFunction
+#define BOOST_SIGNALS2_SLOT_TEMPLATE_SPECIALIZATION
+
+// typename R, typename T1, typename T2, ..., typename TN, typename Combiner, ...
+#define BOOST_SIGNALS2_SIGNAL_TEMPLATE_DECL(arity) \
+ BOOST_SIGNALS2_SIGNATURE_TEMPLATE_DECL(arity), \
+ typename Combiner, \
+ typename Group, \
+ typename GroupCompare, \
+ typename SlotFunction, \
+ typename ExtendedSlotFunction, \
+ typename Mutex
+// typename R, typename T1, typename T2, ..., typename TN, typename Combiner = optional_last_value<R>, ...
+#define BOOST_SIGNALS2_SIGNAL_TEMPLATE_DEFAULTED_DECL(arity) \
+ BOOST_SIGNALS2_SIGNATURE_TEMPLATE_DECL(arity), \
+ typename Combiner = optional_last_value<R>, \
+ typename Group = int, \
+ typename GroupCompare = std::less<Group>, \
+ typename SlotFunction = BOOST_SIGNALS2_FUNCTION_N_DECL(arity), \
+ typename ExtendedSlotFunction = BOOST_SIGNALS2_EXT_FUNCTION_N_DECL(arity), \
+ typename Mutex = signals2::mutex
+#define BOOST_SIGNALS2_SIGNAL_TEMPLATE_SPECIALIZATION_DECL(arity) BOOST_SIGNALS2_SIGNAL_TEMPLATE_DECL(arity)
+#define BOOST_SIGNALS2_SIGNAL_TEMPLATE_SPECIALIZATION
+
+#define BOOST_SIGNALS2_STD_FUNCTIONAL_BASE(result_type) std_functional_base
+
+#define BOOST_SIGNALS2_PP_COMMA_IF(arity) BOOST_PP_COMMA_IF(arity)
+
+#else // BOOST_NO_CXX11_VARIADIC_TEMPLATES
+
+#define BOOST_SIGNALS2_SIGNAL_CLASS_NAME(arity) signal
+#define BOOST_SIGNALS2_WEAK_SIGNAL_CLASS_NAME(arity) weak_signal
+#define BOOST_SIGNALS2_SIGNAL_IMPL_CLASS_NAME(arity) signal_impl
+#define BOOST_SIGNALS2_SIGNATURE_TEMPLATE_DECL(arity) typename Signature
+#define BOOST_SIGNALS2_ARGS_TEMPLATE_INSTANTIATION(arity) Args...
+#define BOOST_SIGNALS2_SIGNATURE_TEMPLATE_INSTANTIATION(arity) R (Args...)
+#define BOOST_SIGNALS2_SIGNATURE_FUNCTION_TYPE(arity) R (Args...)
+#define BOOST_SIGNALS2_ARGS_TEMPLATE_DECL(arity) typename ... Args
+#define BOOST_SIGNALS2_FULL_REF_ARGS(arity) Args & ... args
+#define BOOST_SIGNALS2_SLOT_CLASS_NAME(arity) slot
+#define BOOST_SIGNALS2_EXTENDED_SLOT_TYPE(arity) slot<R (const connection &, Args...), extended_slot_function_type>
+#define BOOST_SIGNALS2_BOUND_EXTENDED_SLOT_FUNCTION_N(arity) bound_extended_slot_function
+#define BOOST_SIGNALS2_BOUND_EXTENDED_SLOT_FUNCTION_INVOKER_N(arity) bound_extended_slot_function_invoker
+#define BOOST_SIGNALS2_FUNCTION_N_DECL(arity) boost::function<Signature>
+#define BOOST_SIGNALS2_PREFIXED_SIGNATURE_TEMPLATE_DECL(arity, prefix) typename prefixSignature
+#define BOOST_SIGNALS2_PREFIXED_SIGNATURE_TEMPLATE_INSTANTIATION(arity, prefix) prefixSignature
+#define BOOST_SIGNALS2_SIGNATURE_FULL_ARGS(arity) Args ... args
+#define BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(arity) args...
+#define BOOST_SIGNALS2_PORTABLE_SIGNATURE(arity, Signature) Signature
+
+#define BOOST_SIGNALS2_SLOT_TEMPLATE_SPECIALIZATION_DECL(arity) \
+ typename SlotFunction, \
+ typename R, \
+ typename ... Args
+#define BOOST_SIGNALS2_SLOT_TEMPLATE_SPECIALIZATION \
+ <R (Args...), SlotFunction>
+
+#define BOOST_SIGNALS2_SIGNAL_TEMPLATE_DECL(arity) \
+ typename Signature, \
+ typename Combiner, \
+ typename Group, \
+ typename GroupCompare, \
+ typename SlotFunction, \
+ typename ExtendedSlotFunction, \
+ typename Mutex
+#define BOOST_SIGNALS2_SIGNAL_TEMPLATE_DEFAULTED_DECL(arity) \
+ typename Signature, \
+ typename Combiner = optional_last_value<typename boost::function_traits<Signature>::result_type>, \
+ typename Group = int, \
+ typename GroupCompare = std::less<Group>, \
+ typename SlotFunction = boost::function<Signature>, \
+ typename ExtendedSlotFunction = typename detail::variadic_extended_signature<Signature>::function_type, \
+ typename Mutex = signals2::mutex
+#define BOOST_SIGNALS2_SIGNAL_TEMPLATE_SPECIALIZATION_DECL(arity) \
+ typename Combiner, \
+ typename Group, \
+ typename GroupCompare, \
+ typename SlotFunction, \
+ typename ExtendedSlotFunction, \
+ typename Mutex, \
+ typename R, \
+ typename ... Args
+#define BOOST_SIGNALS2_SIGNAL_TEMPLATE_SPECIALIZATION <\
+ R (Args...), \
+ Combiner, \
+ Group, \
+ GroupCompare, \
+ SlotFunction, \
+ ExtendedSlotFunction, \
+ Mutex>
+
+#define BOOST_SIGNALS2_STD_FUNCTIONAL_BASE(result_type) \
+ std_functional_base<result_type , Args...>
+
+#define BOOST_SIGNALS2_PP_COMMA_IF(arity) ,
+
+#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
+
+#endif // BOOST_SIGNALS2_SIGNALS_COMMON_MACROS_HPP
diff --git a/3rdParty/Boost/src/boost/signals2/detail/slot_call_iterator.hpp b/3rdParty/Boost/src/boost/signals2/detail/slot_call_iterator.hpp
new file mode 100644
index 0000000..99eec1d
--- /dev/null
+++ b/3rdParty/Boost/src/boost/signals2/detail/slot_call_iterator.hpp
@@ -0,0 +1,147 @@
+// Boost.Signals2 library
+
+// Copyright Douglas Gregor 2001-2004.
+// Copyright Frank Mori Hess 2007-2008.
+// Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#ifndef BOOST_SIGNALS2_SLOT_CALL_ITERATOR_HPP
+#define BOOST_SIGNALS2_SLOT_CALL_ITERATOR_HPP
+
+#include <boost/assert.hpp>
+#include <boost/aligned_storage.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/optional.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/signals2/connection.hpp>
+#include <boost/signals2/slot_base.hpp>
+#include <boost/signals2/detail/auto_buffer.hpp>
+#include <boost/signals2/detail/unique_lock.hpp>
+#include <boost/weak_ptr.hpp>
+
+namespace boost {
+ namespace signals2 {
+ namespace detail {
+ template<typename ResultType, typename Function>
+ class slot_call_iterator_cache
+ {
+ public:
+ slot_call_iterator_cache(const Function &f_arg):
+ f(f_arg),
+ connected_slot_count(0),
+ disconnected_slot_count(0)
+ {}
+ optional<ResultType> result;
+ typedef auto_buffer<void_shared_ptr_variant, store_n_objects<10> > tracked_ptrs_type;
+ tracked_ptrs_type tracked_ptrs;
+ Function f;
+ unsigned connected_slot_count;
+ unsigned disconnected_slot_count;
+ };
+
+ // Generates a slot call iterator. Essentially, this is an iterator that:
+ // - skips over disconnected slots in the underlying list
+ // - calls the connected slots when dereferenced
+ // - caches the result of calling the slots
+ template<typename Function, typename Iterator, typename ConnectionBody>
+ class slot_call_iterator_t
+ : public boost::iterator_facade<slot_call_iterator_t<Function, Iterator, ConnectionBody>,
+ typename Function::result_type,
+ boost::single_pass_traversal_tag,
+ typename Function::result_type const&>
+ {
+ typedef boost::iterator_facade<slot_call_iterator_t<Function, Iterator, ConnectionBody>,
+ typename Function::result_type,
+ boost::single_pass_traversal_tag,
+ typename Function::result_type const&>
+ inherited;
+
+ typedef typename Function::result_type result_type;
+
+ friend class boost::iterator_core_access;
+
+ public:
+ slot_call_iterator_t(Iterator iter_in, Iterator end_in,
+ slot_call_iterator_cache<result_type, Function> &c):
+ iter(iter_in), end(end_in),
+ cache(&c), callable_iter(end_in)
+ {
+ lock_next_callable();
+ }
+
+ typename inherited::reference
+ dereference() const
+ {
+ if (!cache->result) {
+ try
+ {
+ cache->result.reset(cache->f(*iter));
+ }
+ catch(expired_slot &)
+ {
+ (*iter)->disconnect();
+ throw;
+ }
+ }
+ return cache->result.get();
+ }
+
+ void increment()
+ {
+ ++iter;
+ lock_next_callable();
+ cache->result.reset();
+ }
+
+ bool equal(const slot_call_iterator_t& other) const
+ {
+ return iter == other.iter;
+ }
+
+ private:
+ typedef unique_lock<connection_body_base> lock_type;
+
+ void lock_next_callable() const
+ {
+ if(iter == callable_iter)
+ {
+ return;
+ }
+ for(;iter != end; ++iter)
+ {
+ lock_type lock(**iter);
+ cache->tracked_ptrs.clear();
+ (*iter)->nolock_grab_tracked_objects(std::back_inserter(cache->tracked_ptrs));
+ if((*iter)->nolock_nograb_connected())
+ {
+ ++cache->connected_slot_count;
+ }else
+ {
+ ++cache->disconnected_slot_count;
+ }
+ if((*iter)->nolock_nograb_blocked() == false)
+ {
+ callable_iter = iter;
+ break;
+ }
+ }
+ if(iter == end)
+ {
+ callable_iter = end;
+ }
+ }
+
+ mutable Iterator iter;
+ Iterator end;
+ slot_call_iterator_cache<result_type, Function> *cache;
+ mutable Iterator callable_iter;
+ };
+ } // end namespace detail
+ } // end namespace BOOST_SIGNALS_NAMESPACE
+} // end namespace boost
+
+#endif // BOOST_SIGNALS2_SLOT_CALL_ITERATOR_HPP
diff --git a/3rdParty/Boost/src/boost/signals2/detail/slot_groups.hpp b/3rdParty/Boost/src/boost/signals2/detail/slot_groups.hpp
new file mode 100644
index 0000000..5e1853a
--- /dev/null
+++ b/3rdParty/Boost/src/boost/signals2/detail/slot_groups.hpp
@@ -0,0 +1,235 @@
+// Boost.Signals2 library
+
+// Copyright Frank Mori Hess 2007-2008.
+// Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#ifndef BOOST_SIGNALS2_SLOT_GROUPS_HPP
+#define BOOST_SIGNALS2_SLOT_GROUPS_HPP
+
+#include <boost/signals2/connection.hpp>
+#include <boost/optional.hpp>
+#include <list>
+#include <map>
+#include <utility>
+
+namespace boost {
+ namespace signals2 {
+ namespace detail {
+ enum slot_meta_group {front_ungrouped_slots, grouped_slots, back_ungrouped_slots};
+ template<typename Group>
+ struct group_key
+ {
+ typedef std::pair<enum slot_meta_group, boost::optional<Group> > type;
+ };
+ template<typename Group, typename GroupCompare>
+ class group_key_less
+ {
+ public:
+ group_key_less()
+ {}
+ group_key_less(const GroupCompare &group_compare): _group_compare(group_compare)
+ {}
+ bool operator ()(const typename group_key<Group>::type &key1, const typename group_key<Group>::type &key2) const
+ {
+ if(key1.first != key2.first) return key1.first < key2.first;
+ if(key1.first != grouped_slots) return false;
+ return _group_compare(key1.second.get(), key2.second.get());
+ }
+ private:
+ GroupCompare _group_compare;
+ };
+ template<typename Group, typename GroupCompare, typename ValueType>
+ class grouped_list
+ {
+ public:
+ typedef group_key_less<Group, GroupCompare> group_key_compare_type;
+ private:
+ typedef std::list<ValueType> list_type;
+ typedef std::map
+ <
+ typename group_key<Group>::type,
+ typename list_type::iterator,
+ group_key_compare_type
+ > map_type;
+ typedef typename map_type::iterator map_iterator;
+ typedef typename map_type::const_iterator const_map_iterator;
+ public:
+ typedef typename list_type::iterator iterator;
+ typedef typename list_type::const_iterator const_iterator;
+ typedef typename group_key<Group>::type group_key_type;
+
+ grouped_list(const group_key_compare_type &group_key_compare):
+ _group_key_compare(group_key_compare)
+ {}
+ grouped_list(const grouped_list &other): _list(other._list),
+ _group_map(other._group_map), _group_key_compare(other._group_key_compare)
+ {
+ // fix up _group_map
+ typename map_type::const_iterator other_map_it;
+ typename list_type::iterator this_list_it = _list.begin();
+ typename map_type::iterator this_map_it = _group_map.begin();
+ for(other_map_it = other._group_map.begin();
+ other_map_it != other._group_map.end();
+ ++other_map_it, ++this_map_it)
+ {
+ BOOST_ASSERT(this_map_it != _group_map.end());
+ this_map_it->second = this_list_it;
+ typename list_type::const_iterator other_list_it = other.get_list_iterator(other_map_it);
+ typename map_type::const_iterator other_next_map_it = other_map_it;
+ ++other_next_map_it;
+ typename list_type::const_iterator other_next_list_it = other.get_list_iterator(other_next_map_it);
+ while(other_list_it != other_next_list_it)
+ {
+ ++other_list_it;
+ ++this_list_it;
+ }
+ }
+ }
+ iterator begin()
+ {
+ return _list.begin();
+ }
+ iterator end()
+ {
+ return _list.end();
+ }
+ iterator lower_bound(const group_key_type &key)
+ {
+ map_iterator map_it = _group_map.lower_bound(key);
+ return get_list_iterator(map_it);
+ }
+ iterator upper_bound(const group_key_type &key)
+ {
+ map_iterator map_it = _group_map.upper_bound(key);
+ return get_list_iterator(map_it);
+ }
+ void push_front(const group_key_type &key, const ValueType &value)
+ {
+ map_iterator map_it;
+ if(key.first == front_ungrouped_slots)
+ {// optimization
+ map_it = _group_map.begin();
+ }else
+ {
+ map_it = _group_map.lower_bound(key);
+ }
+ m_insert(map_it, key, value);
+ }
+ void push_back(const group_key_type &key, const ValueType &value)
+ {
+ map_iterator map_it;
+ if(key.first == back_ungrouped_slots)
+ {// optimization
+ map_it = _group_map.end();
+ }else
+ {
+ map_it = _group_map.upper_bound(key);
+ }
+ m_insert(map_it, key, value);
+ }
+ void erase(const group_key_type &key)
+ {
+ map_iterator map_it = _group_map.lower_bound(key);
+ iterator begin_list_it = get_list_iterator(map_it);
+ iterator end_list_it = upper_bound(key);
+ if(begin_list_it != end_list_it)
+ {
+ _list.erase(begin_list_it, end_list_it);
+ _group_map.erase(map_it);
+ }
+ }
+ iterator erase(const group_key_type &key, const iterator &it)
+ {
+ BOOST_ASSERT(it != _list.end());
+ map_iterator map_it = _group_map.lower_bound(key);
+ BOOST_ASSERT(map_it != _group_map.end());
+ BOOST_ASSERT(weakly_equivalent(map_it->first, key));
+ if(map_it->second == it)
+ {
+ iterator next = it;
+ ++next;
+ // if next is in same group
+ if(next != upper_bound(key))
+ {
+ _group_map[key] = next;
+ }else
+ {
+ _group_map.erase(map_it);
+ }
+ }
+ return _list.erase(it);
+ }
+ void clear()
+ {
+ _list.clear();
+ _group_map.clear();
+ }
+ private:
+ /* Suppress default assignment operator, since it has the wrong semantics. */
+ grouped_list& operator=(const grouped_list &other);
+
+ bool weakly_equivalent(const group_key_type &arg1, const group_key_type &arg2)
+ {
+ if(_group_key_compare(arg1, arg2)) return false;
+ if(_group_key_compare(arg2, arg1)) return false;
+ return true;
+ }
+ void m_insert(const map_iterator &map_it, const group_key_type &key, const ValueType &value)
+ {
+ iterator list_it = get_list_iterator(map_it);
+ iterator new_it = _list.insert(list_it, value);
+ if(map_it != _group_map.end() && weakly_equivalent(key, map_it->first))
+ {
+ _group_map.erase(map_it);
+ }
+ map_iterator lower_bound_it = _group_map.lower_bound(key);
+ if(lower_bound_it == _group_map.end() ||
+ weakly_equivalent(lower_bound_it->first, key) == false)
+ {
+ /* doing the following instead of just
+ _group_map[key] = new_it;
+ to avoid bogus error when enabling checked iterators with g++ */
+ _group_map.insert(typename map_type::value_type(key, new_it));
+ }
+ }
+ iterator get_list_iterator(const const_map_iterator &map_it)
+ {
+ iterator list_it;
+ if(map_it == _group_map.end())
+ {
+ list_it = _list.end();
+ }else
+ {
+ list_it = map_it->second;
+ }
+ return list_it;
+ }
+ const_iterator get_list_iterator(const const_map_iterator &map_it) const
+ {
+ const_iterator list_it;
+ if(map_it == _group_map.end())
+ {
+ list_it = _list.end();
+ }else
+ {
+ list_it = map_it->second;
+ }
+ return list_it;
+ }
+
+ list_type _list;
+ // holds iterators to first list item in each group
+ map_type _group_map;
+ group_key_compare_type _group_key_compare;
+ };
+ } // end namespace detail
+ enum connect_position { at_back, at_front };
+ } // end namespace signals2
+} // end namespace boost
+
+#endif // BOOST_SIGNALS2_SLOT_GROUPS_HPP
diff --git a/3rdParty/Boost/src/boost/signals2/detail/slot_template.hpp b/3rdParty/Boost/src/boost/signals2/detail/slot_template.hpp
new file mode 100644
index 0000000..fc19f51
--- /dev/null
+++ b/3rdParty/Boost/src/boost/signals2/detail/slot_template.hpp
@@ -0,0 +1,187 @@
+// Boost.Signals2 library
+
+// Copyright Frank Mori Hess 2007-2008.
+// Copyright Timmo Stange 2007.
+// Copyright Douglas Gregor 2001-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+// This file is included iteratively, and should not be protected from multiple inclusion
+
+#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+#define BOOST_SIGNALS2_NUM_ARGS BOOST_PP_ITERATION()
+#else
+#define BOOST_SIGNALS2_NUM_ARGS 1
+#endif
+
+
+namespace boost
+{
+ namespace signals2
+ {
+#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+ template<typename Signature, typename SlotFunction> class slot;
+#else
+ template<typename Signature, typename SlotFunction = boost::function<Signature> >
+ class slot;
+
+#if BOOST_WORKAROUND(BOOST_MSVC, <= 1900)
+ template<typename Signature, typename SlotFunction> class slot{};
+#endif
+#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
+
+ template<BOOST_SIGNALS2_SLOT_TEMPLATE_SPECIALIZATION_DECL(BOOST_SIGNALS2_NUM_ARGS)>
+ class BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS) BOOST_SIGNALS2_SLOT_TEMPLATE_SPECIALIZATION
+ : public slot_base, public detail::BOOST_SIGNALS2_STD_FUNCTIONAL_BASE(R)
+
+ {
+ public:
+ template<BOOST_SIGNALS2_PREFIXED_SIGNATURE_TEMPLATE_DECL(BOOST_SIGNALS2_NUM_ARGS, Other), typename OtherSlotFunction>
+ friend class BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS);
+
+ typedef SlotFunction slot_function_type;
+ typedef R result_type;
+ typedef typename mpl::identity<BOOST_SIGNALS2_SIGNATURE_FUNCTION_TYPE(BOOST_SIGNALS2_NUM_ARGS)>::type signature_type;
+
+#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+
+// typedef Tn argn_type;
+#define BOOST_SIGNALS2_MISC_STATEMENT(z, n, data) \
+ typedef BOOST_PP_CAT(T, BOOST_PP_INC(n)) BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(n)), _type);
+ BOOST_PP_REPEAT(BOOST_SIGNALS2_NUM_ARGS, BOOST_SIGNALS2_MISC_STATEMENT, ~)
+#undef BOOST_SIGNALS2_MISC_STATEMENT
+#if BOOST_SIGNALS2_NUM_ARGS == 1
+ typedef arg1_type argument_type;
+#elif BOOST_SIGNALS2_NUM_ARGS == 2
+ typedef arg1_type first_argument_type;
+ typedef arg2_type second_argument_type;
+#endif
+
+ template<unsigned n> class arg : public
+ detail::BOOST_SIGNALS2_PREPROCESSED_ARG_N_TYPE_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)
+ <n BOOST_SIGNALS2_PP_COMMA_IF(BOOST_SIGNALS2_NUM_ARGS)
+ BOOST_SIGNALS2_ARGS_TEMPLATE_INSTANTIATION(BOOST_SIGNALS2_NUM_ARGS)>
+ {};
+
+ BOOST_STATIC_CONSTANT(int, arity = BOOST_SIGNALS2_NUM_ARGS);
+
+#else // BOOST_NO_CXX11_VARIADIC_TEMPLATES
+
+ template<unsigned n> class arg
+ {
+ public:
+ typedef typename detail::variadic_arg_type<n, Args...>::type type;
+ };
+ BOOST_STATIC_CONSTANT(int, arity = sizeof...(Args));
+
+#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
+
+ template<typename F>
+ BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)(const F& f)
+ {
+ init_slot_function(f);
+ }
+ // copy constructors
+#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+ template<BOOST_SIGNALS2_PREFIXED_SIGNATURE_TEMPLATE_DECL(BOOST_SIGNALS2_NUM_ARGS, Other), typename OtherSlotFunction>
+ BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)(const BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)
+ <BOOST_SIGNALS2_PREFIXED_SIGNATURE_TEMPLATE_INSTANTIATION(BOOST_SIGNALS2_NUM_ARGS, Other), OtherSlotFunction> &other_slot):
+ slot_base(other_slot), _slot_function(other_slot._slot_function)
+ {
+ }
+#endif
+ template<typename Signature, typename OtherSlotFunction>
+ BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)(const slot<Signature, OtherSlotFunction> &other_slot):
+ slot_base(other_slot), _slot_function(other_slot._slot_function)
+ {
+ }
+ // bind syntactic sugar
+ BOOST_SIGNALS2_SLOT_N_BINDING_CONSTRUCTORS
+ // invocation
+ R operator()(BOOST_SIGNALS2_SIGNATURE_FULL_ARGS(BOOST_SIGNALS2_NUM_ARGS))
+ {
+ locked_container_type locked_objects = lock();
+ return _slot_function(BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS));
+ }
+ R operator()(BOOST_SIGNALS2_SIGNATURE_FULL_ARGS(BOOST_SIGNALS2_NUM_ARGS)) const
+ {
+ locked_container_type locked_objects = lock();
+ return _slot_function(BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS));
+ }
+ // tracking
+ BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)& track(const weak_ptr<void> &tracked) {
+ _tracked_objects.push_back(tracked);
+ return *this;
+ }
+ BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)& track(const signal_base &signal)
+ {
+ track_signal(signal);
+ return *this;
+ }
+ BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)& track(const slot_base &slot)
+ {
+ tracked_container_type::const_iterator it;
+ for(it = slot.tracked_objects().begin(); it != slot.tracked_objects().end(); ++it)
+ {
+ _tracked_objects.push_back(*it);
+ }
+ return *this;
+ }
+ template<typename ForeignWeakPtr>
+ BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)& track_foreign(const ForeignWeakPtr &tracked,
+ typename weak_ptr_traits<ForeignWeakPtr>::shared_type * /*SFINAE*/ = 0)
+ {
+ _tracked_objects.push_back(detail::foreign_void_weak_ptr(tracked));
+ return *this;
+ }
+ template<typename ForeignSharedPtr>
+ BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)& track_foreign(const ForeignSharedPtr &tracked,
+ typename shared_ptr_traits<ForeignSharedPtr>::weak_type * /*SFINAE*/ = 0)
+ {
+ _tracked_objects.push_back
+ (
+ detail::foreign_void_weak_ptr
+ (
+ typename shared_ptr_traits<ForeignSharedPtr>::weak_type(tracked)
+ )
+ );
+ return *this;
+ }
+
+ const slot_function_type& slot_function() const {return _slot_function;}
+ slot_function_type& slot_function() {return _slot_function;}
+ private:
+ template<typename F>
+ void init_slot_function(const F& f)
+ {
+ _slot_function = detail::get_invocable_slot(f, detail::tag_type(f));
+ signals2::detail::tracked_objects_visitor visitor(this);
+ boost::visit_each(visitor, f);
+ }
+
+ SlotFunction _slot_function;
+ };
+
+#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+ namespace detail
+ {
+ template<unsigned arity, typename Signature, typename SlotFunction>
+ class slotN;
+ // partial template specialization
+ template<typename Signature, typename SlotFunction>
+ class slotN<BOOST_SIGNALS2_NUM_ARGS, Signature, SlotFunction>
+ {
+ public:
+ typedef BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)<
+ BOOST_SIGNALS2_PORTABLE_SIGNATURE(BOOST_SIGNALS2_NUM_ARGS, Signature),
+ SlotFunction> type;
+ };
+ }
+#endif
+ } // end namespace signals2
+} // end namespace boost
+
+#undef BOOST_SIGNALS2_NUM_ARGS
diff --git a/3rdParty/Boost/src/boost/signals2/detail/tracked_objects_visitor.hpp b/3rdParty/Boost/src/boost/signals2/detail/tracked_objects_visitor.hpp
new file mode 100644
index 0000000..71a1d50
--- /dev/null
+++ b/3rdParty/Boost/src/boost/signals2/detail/tracked_objects_visitor.hpp
@@ -0,0 +1,98 @@
+// Boost.Signals2 library
+
+// Copyright Frank Mori Hess 2007-2008.
+// Copyright Timmo Stange 2007.
+// Copyright Douglas Gregor 2001-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#ifndef BOOST_SIGNALS2_TRACKED_OBJECTS_VISITOR_HPP
+#define BOOST_SIGNALS2_TRACKED_OBJECTS_VISITOR_HPP
+
+#include <boost/mpl/bool.hpp>
+#include <boost/ref.hpp>
+#include <boost/signals2/detail/signals_common.hpp>
+#include <boost/signals2/slot_base.hpp>
+#include <boost/signals2/trackable.hpp>
+#include <boost/type_traits/is_function.hpp>
+#include <boost/type_traits/is_pointer.hpp>
+#include <boost/type_traits/remove_pointer.hpp>
+#include <boost/utility/addressof.hpp>
+
+namespace boost
+{
+ namespace signals2
+ {
+ namespace detail
+ {
+ // Visitor to collect tracked objects from a bound function.
+ class tracked_objects_visitor
+ {
+ public:
+ tracked_objects_visitor(slot_base *slot) : slot_(slot)
+ {}
+ template<typename T>
+ void operator()(const T& t) const
+ {
+ m_visit_reference_wrapper(t, mpl::bool_<is_reference_wrapper<T>::value>());
+ }
+ private:
+ template<typename T>
+ void m_visit_reference_wrapper(const reference_wrapper<T> &t, const mpl::bool_<true> &) const
+ {
+ m_visit_pointer(t.get_pointer(), mpl::bool_<true>());
+ }
+ template<typename T>
+ void m_visit_reference_wrapper(const T &t, const mpl::bool_<false> &) const
+ {
+ m_visit_pointer(t, mpl::bool_<is_pointer<T>::value>());
+ }
+ template<typename T>
+ void m_visit_pointer(const T &t, const mpl::bool_<true> &) const
+ {
+ m_visit_not_function_pointer(t, mpl::bool_<!is_function<typename remove_pointer<T>::type>::value>());
+ }
+ template<typename T>
+ void m_visit_pointer(const T &t, const mpl::bool_<false> &) const
+ {
+ m_visit_pointer(boost::addressof(t), mpl::bool_<true>());
+ }
+ template<typename T>
+ void m_visit_not_function_pointer(const T *t, const mpl::bool_<true> &) const
+ {
+ m_visit_signal(t, mpl::bool_<is_signal<T>::value>());
+ }
+ template<typename T>
+ void m_visit_not_function_pointer(const T &, const mpl::bool_<false> &) const
+ {}
+ template<typename T>
+ void m_visit_signal(const T *signal, const mpl::bool_<true> &) const
+ {
+ if(signal)
+ slot_->track_signal(*signal);
+ }
+ template<typename T>
+ void m_visit_signal(const T &t, const mpl::bool_<false> &) const
+ {
+ add_if_trackable(t);
+ }
+ void add_if_trackable(const trackable *trackable) const
+ {
+ if(trackable)
+ slot_->_tracked_objects.push_back(trackable->get_shared_ptr());
+ }
+ void add_if_trackable(const void *) const {}
+
+ mutable slot_base * slot_;
+ };
+
+
+ } // end namespace detail
+ } // end namespace signals2
+} // end namespace boost
+
+#endif // BOOST_SIGNALS2_TRACKED_OBJECTS_VISITOR_HPP
+
diff --git a/3rdParty/Boost/src/boost/signals2/detail/unique_lock.hpp b/3rdParty/Boost/src/boost/signals2/detail/unique_lock.hpp
new file mode 100644
index 0000000..13fecf2
--- /dev/null
+++ b/3rdParty/Boost/src/boost/signals2/detail/unique_lock.hpp
@@ -0,0 +1,42 @@
+/*
+ Provides a basic subset of boost::unique_lock functionality. Provided only because
+ including boost/thread/locks.hpp requires linking to thread library
+*/
+// Copyright Frank Mori Hess 2008.
+// Distributed under the 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/signals2 for library home page.
+
+#ifndef BOOST_SIGNALS2_UNIQUE_LOCK_HPP
+#define BOOST_SIGNALS2_UNIQUE_LOCK_HPP
+
+#include <boost/noncopyable.hpp>
+
+namespace boost
+{
+ namespace signals2
+ {
+ namespace detail
+ {
+ template<typename Mutex>
+ class unique_lock: public noncopyable
+ {
+ public:
+ unique_lock(Mutex &m): _mutex(m)
+ {
+ _mutex.lock();
+ }
+ ~unique_lock()
+ {
+ _mutex.unlock();
+ }
+ private:
+ Mutex &_mutex;
+ };
+ } // namespace detail
+ } // namespace signals2
+} // namespace boost
+
+#endif // BOOST_SIGNALS2_UNIQUE_LOCK_HPP
diff --git a/3rdParty/Boost/src/boost/signals2/detail/variadic_arg_type.hpp b/3rdParty/Boost/src/boost/signals2/detail/variadic_arg_type.hpp
new file mode 100644
index 0000000..14d54b2
--- /dev/null
+++ b/3rdParty/Boost/src/boost/signals2/detail/variadic_arg_type.hpp
@@ -0,0 +1,49 @@
+// Copyright Frank Mori Hess 2009
+//
+// Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#ifndef BOOST_SIGNALS2_DETAIL_VARIADIC_ARG_TYPE_HPP
+#define BOOST_SIGNALS2_DETAIL_VARIADIC_ARG_TYPE_HPP
+
+#include <functional>
+
+namespace boost
+{
+ namespace signals2
+ {
+ namespace detail
+ {
+ template<unsigned, typename ... Args> class variadic_arg_type;
+
+ template<typename T, typename ... Args> class variadic_arg_type<0, T, Args...>
+ {
+ public:
+ typedef T type;
+ };
+
+ template<unsigned n, typename T, typename ... Args> class variadic_arg_type<n, T, Args...>
+ {
+ public:
+ typedef typename variadic_arg_type<n - 1, Args...>::type type;
+ };
+
+ template <typename R, typename ... Args>
+ struct std_functional_base
+ {};
+ template <typename R, typename T1>
+ struct std_functional_base<R, T1>: public std::unary_function<T1, R>
+ {};
+ template <typename R, typename T1, typename T2>
+ struct std_functional_base<R, T1, T2>: public std::binary_function<T1, T2, R>
+ {};
+ } // namespace detail
+ } // namespace signals2
+} // namespace boost
+
+
+#endif // BOOST_SIGNALS2_DETAIL_VARIADIC_ARG_TYPE_HPP
diff --git a/3rdParty/Boost/src/boost/signals2/detail/variadic_slot_invoker.hpp b/3rdParty/Boost/src/boost/signals2/detail/variadic_slot_invoker.hpp
new file mode 100644
index 0000000..6d9227e
--- /dev/null
+++ b/3rdParty/Boost/src/boost/signals2/detail/variadic_slot_invoker.hpp
@@ -0,0 +1,139 @@
+/*
+ Helper class used by variadic implementation of variadic boost::signals2::signal.
+
+ Author: Frank Mori Hess <fmhess@users.sourceforge.net>
+ Begin: 2009-05-27
+*/
+// Copyright Frank Mori Hess 2009
+// Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#ifndef BOOST_SIGNALS2_DETAIL_VARIADIC_SLOT_INVOKER_HPP
+#define BOOST_SIGNALS2_DETAIL_VARIADIC_SLOT_INVOKER_HPP
+
+#if defined(_MSVC_VER)
+# pragma warning(push)
+# pragma warning(disable:4100) // unreferenced formal parameter
+#endif
+
+#include <boost/mpl/size_t.hpp>
+#include <boost/signals2/detail/variadic_arg_type.hpp>
+
+// if compiler has std::tuple use it instead of boost::tuple
+// because boost::tuple does not have variadic template support at present.
+#ifdef BOOST_NO_CXX11_HDR_TUPLE
+#include <boost/tuple/tuple.hpp>
+#define BOOST_SIGNALS2_TUPLE boost::tuple
+#define BOOST_SIGNALS2_GET boost::get
+#else
+#include <tuple>
+#define BOOST_SIGNALS2_TUPLE std::tuple
+#define BOOST_SIGNALS2_GET std::get
+#endif
+
+namespace boost
+{
+ namespace signals2
+ {
+ namespace detail
+ {
+ template<unsigned ... values> class unsigned_meta_array {};
+
+ template<typename UnsignedMetaArray, unsigned n> class unsigned_meta_array_appender;
+
+ template<unsigned n, unsigned ... Args>
+ class unsigned_meta_array_appender<unsigned_meta_array<Args...>, n>
+ {
+ public:
+ typedef unsigned_meta_array<Args..., n> type;
+ };
+
+ template<unsigned n> class make_unsigned_meta_array;
+
+ template<> class make_unsigned_meta_array<0>
+ {
+ public:
+ typedef unsigned_meta_array<> type;
+ };
+
+ template<> class make_unsigned_meta_array<1>
+ {
+ public:
+ typedef unsigned_meta_array<0> type;
+ };
+
+ template<unsigned n> class make_unsigned_meta_array
+ {
+ public:
+ typedef typename unsigned_meta_array_appender<typename make_unsigned_meta_array<n-1>::type, n - 1>::type type;
+ };
+
+ template<typename R>
+ class call_with_tuple_args
+ {
+ public:
+ typedef R result_type;
+
+ template<typename Func, typename ... Args, std::size_t N>
+ R operator()(Func &func, BOOST_SIGNALS2_TUPLE<Args...> args, mpl::size_t<N>) const
+ {
+ typedef typename make_unsigned_meta_array<N>::type indices_type;
+ typename Func::result_type *resolver = 0;
+ return m_invoke(resolver, func, indices_type(), args);
+ }
+ private:
+ template<typename T, typename Func, unsigned ... indices, typename ... Args>
+ R m_invoke(T *, Func &func, unsigned_meta_array<indices...>, BOOST_SIGNALS2_TUPLE<Args...> args) const
+ {
+ return func(BOOST_SIGNALS2_GET<indices>(args)...);
+ }
+ template<typename Func, unsigned ... indices, typename ... Args>
+ R m_invoke(void *, Func &func, unsigned_meta_array<indices...>, BOOST_SIGNALS2_TUPLE<Args...> args) const
+ {
+ func(BOOST_SIGNALS2_GET<indices>(args)...);
+ return R();
+ }
+ };
+
+ template<typename R, typename ... Args>
+ class variadic_slot_invoker
+ {
+ public:
+ typedef R result_type;
+
+ variadic_slot_invoker(Args & ... args): _args(args...)
+ {}
+ template<typename ConnectionBodyType>
+ result_type operator ()(const ConnectionBodyType &connectionBody) const
+ {
+ result_type *resolver = 0;
+ return m_invoke(connectionBody,
+ resolver);
+ }
+ private:
+ template<typename ConnectionBodyType>
+ result_type m_invoke(const ConnectionBodyType &connectionBody,
+ const void_type *) const
+ {
+ return call_with_tuple_args<result_type>()(connectionBody->slot.slot_function(), _args, mpl::size_t<sizeof...(Args)>());
+ }
+ template<typename ConnectionBodyType>
+ result_type m_invoke(const ConnectionBodyType &connectionBody, ...) const
+ {
+ return call_with_tuple_args<result_type>()(connectionBody->slot.slot_function(), _args, mpl::size_t<sizeof...(Args)>());
+ }
+ BOOST_SIGNALS2_TUPLE<Args& ...> _args;
+ };
+ } // namespace detail
+ } // namespace signals2
+} // namespace boost
+
+#if defined(_MSVC_VER)
+# pragma warning(pop)
+#endif
+
+#endif // BOOST_SIGNALS2_DETAIL_VARIADIC_SLOT_INVOKER_HPP