diff options
author | Tobias Markmann <tm@ayena.de> | 2016-04-05 13:17:19 (GMT) |
---|---|---|
committer | Tobias Markmann <tm@ayena.de> | 2016-04-05 19:42:39 (GMT) |
commit | 2b560b129b7a31fc8cc07f618e763c95a22bf832 (patch) | |
tree | 73e72cdc758b79d01485dc28dcedd48b26859ae8 /3rdParty/Boost/src/boost/signals2 | |
parent | 3c560e31b0f168da917e8d566db01fd1cd997d86 (diff) | |
download | swift-2b560b129b7a31fc8cc07f618e763c95a22bf832.zip swift-2b560b129b7a31fc8cc07f618e763c95a22bf832.tar.bz2 |
Migrate to Boost.Signals2 from Boost.Signals
Boost.Signals was deprecated and is not improved further.
This patch removes Boost.Signals from 3rdParty and adds
Boost.Signals2 and its dependencies.
Also removed the Qt signals compatibility file
Swiften/Base/boost_bsignals.h.
Test-Information:
Build and ran unit tests on OS X 10.11.4. Confirmed successful
login using Swift client.
Change-Id: Ie6e3b2d15aac2462cda95401582f5287a479fb54
Diffstat (limited to '3rdParty/Boost/src/boost/signals2')
41 files changed, 5769 insertions, 0 deletions
diff --git a/3rdParty/Boost/src/boost/signals2/connection.hpp b/3rdParty/Boost/src/boost/signals2/connection.hpp new file mode 100644 index 0000000..0ab4dac --- /dev/null +++ b/3rdParty/Boost/src/boost/signals2/connection.hpp @@ -0,0 +1,297 @@ +/* + boost::signals2::connection provides a handle to a signal/slot connection. + + Author: Frank Mori Hess <fmhess@users.sourceforge.net> + Begin: 2007-01-23 +*/ +// Copyright Frank Mori Hess 2007-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_CONNECTION_HPP +#define BOOST_SIGNALS2_CONNECTION_HPP + +#include <boost/function.hpp> +#include <boost/mpl/bool.hpp> +#include <boost/noncopyable.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/signals2/detail/null_output_iterator.hpp> +#include <boost/signals2/detail/unique_lock.hpp> +#include <boost/signals2/slot.hpp> +#include <boost/weak_ptr.hpp> + +namespace boost +{ + namespace signals2 + { + extern inline void null_deleter(const void*) {} + namespace detail + { + class connection_body_base + { + public: + connection_body_base(): + _connected(true) + { + } + virtual ~connection_body_base() {} + void disconnect() + { + unique_lock<connection_body_base> local_lock(*this); + nolock_disconnect(); + } + void nolock_disconnect() + { + _connected = false; + } + virtual bool connected() const = 0; + shared_ptr<void> get_blocker() + { + unique_lock<connection_body_base> local_lock(*this); + shared_ptr<void> blocker = _weak_blocker.lock(); + if(blocker == shared_ptr<void>()) + { + blocker.reset(this, &null_deleter); + _weak_blocker = blocker; + } + return blocker; + } + bool blocked() const + { + return !_weak_blocker.expired(); + } + bool nolock_nograb_blocked() const + { + return nolock_nograb_connected() == false || blocked(); + } + bool nolock_nograb_connected() const {return _connected;} + // expose part of Lockable concept of mutex + virtual void lock() = 0; + virtual void unlock() = 0; + + protected: + + mutable bool _connected; + weak_ptr<void> _weak_blocker; + }; + + template<typename GroupKey, typename SlotType, typename Mutex> + class connection_body: public connection_body_base + { + public: + typedef Mutex mutex_type; + connection_body(const SlotType &slot_in): + slot(slot_in) + { + } + virtual ~connection_body() {} + virtual bool connected() const + { + unique_lock<mutex_type> local_lock(_mutex); + nolock_grab_tracked_objects(detail::null_output_iterator()); + return nolock_nograb_connected(); + } + const GroupKey& group_key() const {return _group_key;} + void set_group_key(const GroupKey &key) {_group_key = key;} + bool nolock_slot_expired() const + { + bool expired = slot.expired(); + if(expired == true) + { + _connected = false; + } + return expired; + } + template<typename OutputIterator> + void nolock_grab_tracked_objects(OutputIterator inserter) const + { + slot_base::tracked_container_type::const_iterator it; + for(it = slot.tracked_objects().begin(); + it != slot.tracked_objects().end(); + ++it) + { + void_shared_ptr_variant locked_object + ( + apply_visitor + ( + detail::lock_weak_ptr_visitor(), + *it + ) + ); + if(apply_visitor(detail::expired_weak_ptr_visitor(), *it)) + { + _connected = false; + return; + } + *inserter++ = locked_object; + } + } + // expose Lockable concept of mutex + virtual void lock() + { + _mutex.lock(); + } + virtual void unlock() + { + _mutex.unlock(); + } + SlotType slot; + private: + mutable mutex_type _mutex; + GroupKey _group_key; + }; + } + + class shared_connection_block; + + class connection + { + public: + friend class shared_connection_block; + + connection() {} + connection(const connection &other): _weak_connection_body(other._weak_connection_body) + {} + connection(const boost::weak_ptr<detail::connection_body_base> &connectionBody): + _weak_connection_body(connectionBody) + {} + + // move support +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + connection(connection && other): _weak_connection_body(std::move(other._weak_connection_body)) + { + // make sure other is reset, in case it is a scoped_connection (so it + // won't disconnect on destruction after being moved away from). + other._weak_connection_body.reset(); + } + connection & operator=(connection && other) + { + if(&other == this) return *this; + _weak_connection_body = std::move(other._weak_connection_body); + // make sure other is reset, in case it is a scoped_connection (so it + // won't disconnect on destruction after being moved away from). + other._weak_connection_body.reset(); + return *this; + } +#endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + connection & operator=(const connection & other) + { + if(&other == this) return *this; + _weak_connection_body = other._weak_connection_body; + return *this; + } + + ~connection() {} + void disconnect() const + { + boost::shared_ptr<detail::connection_body_base> connectionBody(_weak_connection_body.lock()); + if(connectionBody == 0) return; + connectionBody->disconnect(); + } + bool connected() const + { + boost::shared_ptr<detail::connection_body_base> connectionBody(_weak_connection_body.lock()); + if(connectionBody == 0) return false; + return connectionBody->connected(); + } + bool blocked() const + { + boost::shared_ptr<detail::connection_body_base> connectionBody(_weak_connection_body.lock()); + if(connectionBody == 0) return true; + return connectionBody->blocked(); + } + bool operator==(const connection& other) const + { + boost::shared_ptr<detail::connection_body_base> connectionBody(_weak_connection_body.lock()); + boost::shared_ptr<detail::connection_body_base> otherConnectionBody(other._weak_connection_body.lock()); + return connectionBody == otherConnectionBody; + } + bool operator!=(const connection& other) const + { + return !(*this == other); + } + bool operator<(const connection& other) const + { + boost::shared_ptr<detail::connection_body_base> connectionBody(_weak_connection_body.lock()); + boost::shared_ptr<detail::connection_body_base> otherConnectionBody(other._weak_connection_body.lock()); + return connectionBody < otherConnectionBody; + } + void swap(connection &other) + { + using std::swap; + swap(_weak_connection_body, other._weak_connection_body); + } + protected: + + boost::weak_ptr<detail::connection_body_base> _weak_connection_body; + }; + inline void swap(connection &conn1, connection &conn2) + { + conn1.swap(conn2); + } + + class scoped_connection: public connection + { + public: + scoped_connection() {} + scoped_connection(const connection &other): + connection(other) + {} + ~scoped_connection() + { + disconnect(); + } + scoped_connection& operator=(const connection &rhs) + { + disconnect(); + connection::operator=(rhs); + return *this; + } + + // move support +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + scoped_connection(scoped_connection && other): connection(std::move(other)) + { + } + scoped_connection(connection && other): connection(std::move(other)) + { + } + scoped_connection & operator=(scoped_connection && other) + { + if(&other == this) return *this; + disconnect(); + connection::operator=(std::move(other)); + return *this; + } + scoped_connection & operator=(connection && other) + { + if(&other == this) return *this; + disconnect(); + connection::operator=(std::move(other)); + return *this; + } +#endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + + connection release() + { + connection conn(_weak_connection_body); + _weak_connection_body.reset(); + return conn; + } + private: + scoped_connection(const scoped_connection &other); + scoped_connection& operator=(const scoped_connection &rhs); + }; + // Sun 5.9 compiler doesn't find the swap for base connection class when + // arguments are scoped_connection, so we provide this explicitly. + inline void swap(scoped_connection &conn1, scoped_connection &conn2) + { + conn1.swap(conn2); + } + } +} + +#endif // BOOST_SIGNALS2_CONNECTION_HPP diff --git a/3rdParty/Boost/src/boost/signals2/deconstruct.hpp b/3rdParty/Boost/src/boost/signals2/deconstruct.hpp new file mode 100644 index 0000000..d3eca33 --- /dev/null +++ b/3rdParty/Boost/src/boost/signals2/deconstruct.hpp @@ -0,0 +1,547 @@ +#ifndef BOOST_SIGNALS2_DECONSTRUCT_HPP +#define BOOST_SIGNALS2_DECONSTRUCT_HPP + +// deconstruct.hpp +// +// A factory function for creating a shared_ptr which creates +// an object and its owning shared_ptr with one allocation, similar +// to make_shared<T>(). It also supports postconstructors +// and predestructors through unqualified calls of adl_postconstruct() and +// adl_predestruct, relying on argument-dependent +// lookup to find the appropriate postconstructor or predestructor. +// Passing arguments to postconstructors is also supported. +// +// based on make_shared.hpp and make_shared_access patch from Michael Marcin +// +// Copyright (c) 2007, 2008 Peter Dimov +// Copyright (c) 2008 Michael Marcin +// Copyright (c) 2009 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 +// +// See http://www.boost.org +// for more information + +#include <boost/config.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/signals2/deconstruct_ptr.hpp> +#include <boost/type_traits/alignment_of.hpp> +#include <boost/type_traits/remove_const.hpp> +#include <boost/type_traits/type_with_alignment.hpp> +#include <cstddef> +#include <new> + +namespace boost +{ + template<typename T> class enable_shared_from_this; + +namespace signals2 +{ + class deconstruct_access; + +namespace detail +{ + inline void adl_predestruct(...) {} +} // namespace detail + +template<typename T> + class postconstructor_invoker +{ +public: + operator const shared_ptr<T> & () const + { + return postconstruct(); + } + const shared_ptr<T>& postconstruct() const + { + if(!_postconstructed) + { + adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get())); + _postconstructed = true; + } + return _sp; + } +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + template<class... Args> + const shared_ptr<T>& postconstruct(Args && ... args) + { + if(!_postconstructed) + { + adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()), + std::forward<Args>(args)...); + _postconstructed = true; + } + return _sp; + } +#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + template<typename A1> + const shared_ptr<T>& postconstruct(const A1 &a1) const + { + if(!_postconstructed) + { + adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()), + a1); + _postconstructed = true; + } + return _sp; + } + template<typename A1, typename A2> + const shared_ptr<T>& postconstruct(const A1 &a1, const A2 &a2) const + { + if(!_postconstructed) + { + adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()), + a1, a2); + _postconstructed = true; + } + return _sp; + } + template<typename A1, typename A2, typename A3> + const shared_ptr<T>& postconstruct(const A1 &a1, const A2 &a2, const A3 &a3) const + { + if(!_postconstructed) + { + adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()), + a1, a2, a3); + _postconstructed = true; + } + return _sp; + } + template<typename A1, typename A2, typename A3, typename A4> + const shared_ptr<T>& postconstruct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4) const + { + if(!_postconstructed) + { + adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()), + a1, a2, a3, a4); + _postconstructed = true; + } + return _sp; + } + template<typename A1, typename A2, typename A3, typename A4, typename A5> + const shared_ptr<T>& postconstruct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5) const + { + if(!_postconstructed) + { + adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()), + a1, a2, a3, a4, a5); + _postconstructed = true; + } + return _sp; + } + template<typename A1, typename A2, typename A3, typename A4, typename A5, + typename A6> + const shared_ptr<T>& postconstruct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, + const A6 &a6) const + { + if(!_postconstructed) + { + adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()), + a1, a2, a3, a4, a5, a6); + _postconstructed = true; + } + return _sp; + } + template<typename A1, typename A2, typename A3, typename A4, typename A5, + typename A6, typename A7> + const shared_ptr<T>& postconstruct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, + const A6 &a6, const A7 &a7) const + { + if(!_postconstructed) + { + adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()), + a1, a2, a3, a4, a5, a6, a7); + _postconstructed = true; + } + return _sp; + } + template<typename A1, typename A2, typename A3, typename A4, typename A5, + typename A6, typename A7, typename A8> + const shared_ptr<T>& postconstruct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, + const A6 &a6, const A7 &a7, const A8 &a8) const + { + if(!_postconstructed) + { + adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()), + a1, a2, a3, a4, a5, a6, a7, a8); + _postconstructed = true; + } + return _sp; + } + template<typename A1, typename A2, typename A3, typename A4, typename A5, + typename A6, typename A7, typename A8, typename A9> + const shared_ptr<T>& postconstruct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, + const A6 &a6, const A7 &a7, const A8 &a8, const A9 &a9) const + { + if(!_postconstructed) + { + adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()), + a1, a2, a3, a4, a5, a6, a7, a8, a9); + _postconstructed = true; + } + return _sp; + } +#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) +private: + friend class boost::signals2::deconstruct_access; + postconstructor_invoker(const shared_ptr<T> & sp): + _sp(sp), _postconstructed(false) + {} + shared_ptr<T> _sp; + mutable bool _postconstructed; +}; + +namespace detail +{ + +template< std::size_t N, std::size_t A > struct sp_aligned_storage +{ + union type + { + char data_[ N ]; + typename boost::type_with_alignment< A >::type align_; + }; +}; + +template< class T > class deconstruct_deleter +{ +private: + + typedef typename sp_aligned_storage< sizeof( T ), ::boost::alignment_of< T >::value >::type storage_type; + + bool initialized_; + storage_type storage_; + +private: + + void destroy() + { + if( initialized_ ) + { + T* p = reinterpret_cast< T* >( storage_.data_ ); + using boost::signals2::detail::adl_predestruct; + adl_predestruct(const_cast<typename boost::remove_const<T>::type *>(p)); + p->~T(); + initialized_ = false; + } + } + +public: + + deconstruct_deleter(): initialized_( false ) + { + } + + // this copy constructor is an optimization: we don't need to copy the storage_ member, + // and shouldn't be copying anyways after initialized_ becomes true + deconstruct_deleter(const deconstruct_deleter &): initialized_( false ) + { + } + + ~deconstruct_deleter() + { + destroy(); + } + + void operator()( T * ) + { + destroy(); + } + + void * address() + { + return storage_.data_; + } + + void set_initialized() + { + initialized_ = true; + } +}; +} // namespace detail + +class deconstruct_access +{ +public: + + template< class T > + static postconstructor_invoker<T> deconstruct() + { + boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() ); + + detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt ); + + void * pv = pd->address(); + + new( pv ) T(); + pd->set_initialized(); + + boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) ); + boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get()); + return retval; + + } + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + + // Variadic templates, rvalue reference + + template< class T, class... Args > + static postconstructor_invoker<T> deconstruct( Args && ... args ) + { + boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() ); + + detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt ); + + void * pv = pd->address(); + + new( pv ) T( std::forward<Args>( args )... ); + pd->set_initialized(); + + boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) ); + boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get()); + return retval; + } + +#else + + template< class T, class A1 > + static postconstructor_invoker<T> deconstruct( A1 const & a1 ) + { + boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() ); + + detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt ); + + void * pv = pd->address(); + + new( pv ) T( a1 ); + pd->set_initialized(); + + boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) ); + boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get()); + return retval; + } + + template< class T, class A1, class A2 > + static postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2 ) + { + boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() ); + + detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt ); + + void * pv = pd->address(); + + new( pv ) T( a1, a2 ); + pd->set_initialized(); + + boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) ); + boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get()); + return retval; + } + + template< class T, class A1, class A2, class A3 > + static postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3 ) + { + boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() ); + + detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt ); + + void * pv = pd->address(); + + new( pv ) T( a1, a2, a3 ); + pd->set_initialized(); + + boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) ); + boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get()); + return retval; + } + + template< class T, class A1, class A2, class A3, class A4 > + static postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 ) + { + boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() ); + + detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt ); + + void * pv = pd->address(); + + new( pv ) T( a1, a2, a3, a4 ); + pd->set_initialized(); + + boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) ); + boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get()); + return retval; + } + + template< class T, class A1, class A2, class A3, class A4, class A5 > + static postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 ) + { + boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() ); + + detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt ); + + void * pv = pd->address(); + + new( pv ) T( a1, a2, a3, a4, a5 ); + pd->set_initialized(); + + boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) ); + boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get()); + return retval; + } + + template< class T, class A1, class A2, class A3, class A4, class A5, class A6 > + static postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 ) + { + boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() ); + + detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt ); + + void * pv = pd->address(); + + new( pv ) T( a1, a2, a3, a4, a5, a6 ); + pd->set_initialized(); + + boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) ); + boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get()); + return retval; + } + + template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 > + static postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7 ) + { + boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() ); + + detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt ); + + void * pv = pd->address(); + + new( pv ) T( a1, a2, a3, a4, a5, a6, a7 ); + pd->set_initialized(); + + boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) ); + boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get()); + return retval; + } + + template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 > + static postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8 ) + { + boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() ); + + detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt ); + + void * pv = pd->address(); + + new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 ); + pd->set_initialized(); + + boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) ); + boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get()); + return retval; + } + + template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 > + static postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9 ) + { + boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() ); + + detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt ); + + void * pv = pd->address(); + + new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 ); + pd->set_initialized(); + + boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) ); + boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get()); + return retval; + } + +#endif +}; + +// Zero-argument versions +// +// Used even when variadic templates are available because of the new T() vs new T issue + +template< class T > postconstructor_invoker<T> deconstruct() +{ + return deconstruct_access::deconstruct<T>(); +} + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + +// Variadic templates, rvalue reference + +template< class T, class... Args > postconstructor_invoker< T > deconstruct( Args && ... args ) +{ + return deconstruct_access::deconstruct<T>( std::forward<Args>( args )... ); +} + +#else + +// C++03 version + +template< class T, class A1 > +postconstructor_invoker<T> deconstruct( A1 const & a1 ) +{ + return deconstruct_access::deconstruct<T>(a1); +} + +template< class T, class A1, class A2 > +postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2 ) +{ + return deconstruct_access::deconstruct<T>(a1,a2); +} + +template< class T, class A1, class A2, class A3 > +postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3 ) +{ + return deconstruct_access::deconstruct<T>(a1,a2,a3); +} + +template< class T, class A1, class A2, class A3, class A4 > +postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 ) +{ + return deconstruct_access::deconstruct<T>(a1,a2,a3,a4); +} + +template< class T, class A1, class A2, class A3, class A4, class A5 > +postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 ) +{ + return deconstruct_access::deconstruct<T>(a1,a2,a3,a4,a5); +} + +template< class T, class A1, class A2, class A3, class A4, class A5, class A6 > +postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 ) +{ + return deconstruct_access::deconstruct<T>(a1,a2,a3,a4,a5,a6); +} + +template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 > +postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7 ) +{ + return deconstruct_access::deconstruct<T>(a1,a2,a3,a4,a5,a6,a7); +} + +template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 > +postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8 ) +{ + return deconstruct_access::deconstruct<T>(a1,a2,a3,a4,a5,a6,a7,a8); +} + +template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 > +postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9 ) +{ + return deconstruct_access::deconstruct<T>(a1,a2,a3,a4,a5,a6,a7,a8,a9); +} + +#endif + +} // namespace signals2 +} // namespace boost + +#endif // #ifndef BOOST_SIGNALS2_DECONSTRUCT_HPP diff --git a/3rdParty/Boost/src/boost/signals2/deconstruct_ptr.hpp b/3rdParty/Boost/src/boost/signals2/deconstruct_ptr.hpp new file mode 100644 index 0000000..841b19b --- /dev/null +++ b/3rdParty/Boost/src/boost/signals2/deconstruct_ptr.hpp @@ -0,0 +1,84 @@ +// DEPRECATED in favor of adl_postconstruct and adl_predestruct with +// deconstruct<T>(). +// A factory function for creating a shared_ptr that enhances the plain +// shared_ptr constructors by adding support for postconstructors +// and predestructors through the boost::signals2::postconstructible and +// boost::signals2::predestructible base classes. +// +// 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_DECONSTRUCT_PTR_HPP +#define BOOST_SIGNALS2_DECONSTRUCT_PTR_HPP + +#include <boost/assert.hpp> +#include <boost/checked_delete.hpp> +#include <boost/signals2/postconstructible.hpp> +#include <boost/signals2/predestructible.hpp> +#include <boost/shared_ptr.hpp> + +namespace boost +{ + namespace signals2 + { + namespace detail + { + extern inline void do_postconstruct(const postconstructible *ptr) + { + postconstructible *nonconst_ptr = const_cast<postconstructible*>(ptr); + nonconst_ptr->postconstruct(); + } + extern inline void do_postconstruct(...) + { + } + extern inline void do_predestruct(...) + { + } + extern inline void do_predestruct(const predestructible *ptr) + { + try + { + predestructible *nonconst_ptr = const_cast<predestructible*>(ptr); + nonconst_ptr->predestruct(); + } + catch(...) + { + BOOST_ASSERT(false); + } + } + } + + template<typename T> class predestructing_deleter + { + public: + void operator()(const T *ptr) const + { + detail::do_predestruct(ptr); + checked_delete(ptr); + } + }; + + template<typename T> + shared_ptr<T> deconstruct_ptr(T *ptr) + { + if(ptr == 0) return shared_ptr<T>(ptr); + shared_ptr<T> shared(ptr, boost::signals2::predestructing_deleter<T>()); + detail::do_postconstruct(ptr); + return shared; + } + template<typename T, typename D> + shared_ptr<T> deconstruct_ptr(T *ptr, D deleter) + { + shared_ptr<T> shared(ptr, deleter); + if(ptr == 0) return shared; + detail::do_postconstruct(ptr); + return shared; + } + } +} + +#endif // BOOST_SIGNALS2_DECONSTRUCT_PTR_HPP 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 diff --git a/3rdParty/Boost/src/boost/signals2/dummy_mutex.hpp b/3rdParty/Boost/src/boost/signals2/dummy_mutex.hpp new file mode 100644 index 0000000..f2600f1 --- /dev/null +++ b/3rdParty/Boost/src/boost/signals2/dummy_mutex.hpp @@ -0,0 +1,28 @@ +// A model of the Lockable concept from Boost.Thread which +// does nothing. It can be passed as the Mutex template parameter +// for a signal, if the user wishes to disable thread-safety +// (presumably for performance reasons). + +// 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_DUMMY_MUTEX_HPP +#define BOOST_SIGNALS2_DUMMY_MUTEX_HPP + +namespace boost { + namespace signals2 { + class dummy_mutex + { + public: + void lock() {} + bool try_lock() {return true;} + void unlock() {} + }; + } // end namespace signals2 +} // end namespace boost + +#endif // BOOST_SIGNALS2_DUMMY_MUTEX_HPP diff --git a/3rdParty/Boost/src/boost/signals2/expired_slot.hpp b/3rdParty/Boost/src/boost/signals2/expired_slot.hpp new file mode 100644 index 0000000..fa6db22 --- /dev/null +++ b/3rdParty/Boost/src/boost/signals2/expired_slot.hpp @@ -0,0 +1,31 @@ +// Boost.Signals2 library + +// Copyright Frank Mori Hess 2007-2010. +// 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_EXPIRED_SLOT_HPP +#define BOOST_SIGNALS2_EXPIRED_SLOT_HPP + +#include <boost/smart_ptr/bad_weak_ptr.hpp> + +namespace boost +{ + namespace signals2 + { + class expired_slot: public bad_weak_ptr + { + public: + virtual char const * what() const throw() + { + return "boost::signals2::expired_slot"; + } + }; + } +} // end namespace boost + +#endif // BOOST_SIGNALS2_EXPIRED_SLOT_HPP diff --git a/3rdParty/Boost/src/boost/signals2/last_value.hpp b/3rdParty/Boost/src/boost/signals2/last_value.hpp new file mode 100644 index 0000000..51cc541 --- /dev/null +++ b/3rdParty/Boost/src/boost/signals2/last_value.hpp @@ -0,0 +1,78 @@ +// last_value function object (documented as part of Boost.Signals) + +// Copyright Frank Mori Hess 2007. +// Copyright Douglas Gregor 2001-2003. 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_LAST_VALUE_HPP +#define BOOST_SIGNALS2_LAST_VALUE_HPP + +#include <boost/optional.hpp> +#include <boost/signals2/expired_slot.hpp> +#include <boost/throw_exception.hpp> +#include <stdexcept> + +namespace boost { + namespace signals2 { + + // no_slots_error is thrown when we are unable to generate a return value + // due to no slots being connected to the signal. + class no_slots_error: public std::exception + { + public: + virtual const char* what() const throw() {return "boost::signals2::no_slots_error";} + }; + + template<typename T> + class last_value { + public: + typedef T result_type; + + template<typename InputIterator> + T operator()(InputIterator first, InputIterator last) const + { + if(first == last) + { + boost::throw_exception(no_slots_error()); + } + optional<T> value; + while (first != last) + { + try + { + value = *first; + } + catch(const expired_slot &) {} + ++first; + } + if(value) return value.get(); + boost::throw_exception(no_slots_error()); + } + }; + + template<> + class last_value<void> { + public: + typedef void result_type; + template<typename InputIterator> + result_type operator()(InputIterator first, InputIterator last) const + { + while (first != last) + { + try + { + *first; + } + catch(const expired_slot &) {} + ++first; + } + return; + } + }; + } // namespace signals2 +} // namespace boost +#endif // BOOST_SIGNALS2_LAST_VALUE_HPP diff --git a/3rdParty/Boost/src/boost/signals2/mutex.hpp b/3rdParty/Boost/src/boost/signals2/mutex.hpp new file mode 100644 index 0000000..e58aca1 --- /dev/null +++ b/3rdParty/Boost/src/boost/signals2/mutex.hpp @@ -0,0 +1,38 @@ +// +// boost/signals2/mutex.hpp - header-only mutex +// +// Copyright (c) 2002, 2003 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) +// +// boost::signals2::mutex is a modification of +// boost::detail::lightweight_mutex to follow the newer Lockable +// concept of Boost.Thread. +// + +#ifndef BOOST_SIGNALS2_MUTEX_HPP +#define BOOST_SIGNALS2_MUTEX_HPP + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) +# pragma once +#endif + +#include <boost/config.hpp> + +#if !defined(BOOST_HAS_THREADS) +# include <boost/signals2/detail/lwm_nop.hpp> +#elif defined(BOOST_HAS_PTHREADS) +# include <boost/signals2/detail/lwm_pthreads.hpp> +#elif defined(BOOST_HAS_WINTHREADS) +# include <boost/signals2/detail/lwm_win32_cs.hpp> +#else +// Use #define BOOST_DISABLE_THREADS to avoid the error +# error Unrecognized threading platform +#endif + +#endif // #ifndef BOOST_SIGNALS2_MUTEX_HPP diff --git a/3rdParty/Boost/src/boost/signals2/optional_last_value.hpp b/3rdParty/Boost/src/boost/signals2/optional_last_value.hpp new file mode 100644 index 0000000..766e99b --- /dev/null +++ b/3rdParty/Boost/src/boost/signals2/optional_last_value.hpp @@ -0,0 +1,65 @@ +// optional_last_value function object (documented as part of Boost.Signals2) + +// Copyright Frank Mori Hess 2007-2008. +// Copyright Douglas Gregor 2001-2003. +// Distributed under the 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_OPTIONAL_LAST_VALUE_HPP +#define BOOST_SIGNALS2_OPTIONAL_LAST_VALUE_HPP + +#include <boost/optional.hpp> +#include <boost/signals2/expired_slot.hpp> + +namespace boost { + namespace signals2 { + + template<typename T> + class optional_last_value + { + public: + typedef optional<T> result_type; + + template<typename InputIterator> + optional<T> operator()(InputIterator first, InputIterator last) const + { + optional<T> value; + while (first != last) + { + try + { + value = *first; + } + catch(const expired_slot &) {} + ++first; + } + return value; + } + }; + + template<> + class optional_last_value<void> + { + public: + typedef void result_type; + template<typename InputIterator> + result_type operator()(InputIterator first, InputIterator last) const + { + while (first != last) + { + try + { + *first; + } + catch(const expired_slot &) {} + ++first; + } + return; + } + }; + } // namespace signals2 +} // namespace boost +#endif // BOOST_SIGNALS2_OPTIONAL_LAST_VALUE_HPP diff --git a/3rdParty/Boost/src/boost/signals2/postconstructible.hpp b/3rdParty/Boost/src/boost/signals2/postconstructible.hpp new file mode 100644 index 0000000..faa1444 --- /dev/null +++ b/3rdParty/Boost/src/boost/signals2/postconstructible.hpp @@ -0,0 +1,55 @@ +// DEPRECATED in favor of adl_postconstruct with deconstruct<T>(). +// A simple framework for creating objects with postconstructors. +// The objects must inherit from boost::signals2::postconstructible, and +// have their lifetimes managed by +// boost::shared_ptr created with the boost::signals2::deconstruct_ptr() +// function. +// +// 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_POSTCONSTRUCTIBLE_HPP +#define BOOST_SIGNALS2_POSTCONSTRUCTIBLE_HPP + +namespace boost +{ + template<typename T> class shared_ptr; + + namespace signals2 + { + namespace postconstructible_adl_barrier + { + class postconstructible; + } + namespace detail + { + void do_postconstruct(const boost::signals2::postconstructible_adl_barrier::postconstructible *ptr); + } // namespace detail + + namespace postconstructible_adl_barrier + { + class postconstructible + { + public: + friend void detail::do_postconstruct(const postconstructible *ptr); + template<typename T> + friend void adl_postconstruct(const shared_ptr<T> &sp, postconstructible *p) + { + p->postconstruct(); + } + protected: + postconstructible() {} + virtual ~postconstructible() {} + virtual void postconstruct() = 0; + }; + } // namespace postconstructible_adl_barrier + using postconstructible_adl_barrier::postconstructible; + + } +} + +#endif // BOOST_SIGNALS2_POSTCONSTRUCTIBLE_HPP diff --git a/3rdParty/Boost/src/boost/signals2/predestructible.hpp b/3rdParty/Boost/src/boost/signals2/predestructible.hpp new file mode 100644 index 0000000..0f6806d --- /dev/null +++ b/3rdParty/Boost/src/boost/signals2/predestructible.hpp @@ -0,0 +1,46 @@ +// DEPRECATED in favor of adl_predestruct with deconstruct<T>(). +// A simple framework for creating objects with predestructors. +// The objects must inherit from boost::signals2::predestructible, and +// have their lifetimes managed by +// boost::shared_ptr created with the boost::signals2::deconstruct_ptr() +// function. +// +// 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_PREDESTRUCTIBLE_HPP +#define BOOST_SIGNALS2_PREDESTRUCTIBLE_HPP + +namespace boost +{ + namespace signals2 + { + template<typename T> class predestructing_deleter; + + namespace predestructible_adl_barrier + { + class predestructible + { + protected: + predestructible() {} + public: + template<typename T> + friend void adl_postconstruct(const shared_ptr<T> &, ...) + {} + friend void adl_predestruct(predestructible *p) + { + p->predestruct(); + } + virtual ~predestructible() {} + virtual void predestruct() = 0; + }; + } // namespace predestructible_adl_barrier + using predestructible_adl_barrier::predestructible; + } +} + +#endif // BOOST_SIGNALS2_PREDESTRUCTIBLE_HPP diff --git a/3rdParty/Boost/src/boost/signals2/preprocessed_signal.hpp b/3rdParty/Boost/src/boost/signals2/preprocessed_signal.hpp new file mode 100644 index 0000000..28471ba --- /dev/null +++ b/3rdParty/Boost/src/boost/signals2/preprocessed_signal.hpp @@ -0,0 +1,59 @@ +/* + A thread-safe version of Boost.Signals. + + 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) + +// For more information, see http://www.boost.org + +#ifndef BOOST_SIGNALS2_PREPROCESSED_SIGNAL_HPP +#define BOOST_SIGNALS2_PREPROCESSED_SIGNAL_HPP + +#include <boost/preprocessor/arithmetic.hpp> +#include <boost/preprocessor/cat.hpp> +#include <boost/preprocessor/control/expr_if.hpp> +#include <boost/preprocessor/iteration.hpp> +#include <boost/preprocessor/repetition.hpp> +#include <boost/signals2/detail/preprocessed_arg_type.hpp> +#include <boost/type_traits/add_reference.hpp> + +#define BOOST_PP_ITERATION_LIMITS (0, BOOST_SIGNALS2_MAX_ARGS) +#define BOOST_PP_FILENAME_1 <boost/signals2/detail/signal_template.hpp> +#include BOOST_PP_ITERATE() + +namespace boost +{ + namespace signals2 + { + template<typename Signature, + typename Combiner = optional_last_value<typename boost::function_traits<Signature>::result_type>, + typename Group = int, + typename GroupCompare = std::less<Group>, + typename SlotFunction = function<Signature>, + typename ExtendedSlotFunction = typename detail::extended_signature<function_traits<Signature>::arity, Signature>::function_type, + typename Mutex = mutex > + class signal: public detail::signalN<function_traits<Signature>::arity, + Signature, Combiner, Group, GroupCompare, SlotFunction, ExtendedSlotFunction, Mutex>::type + { + private: + typedef typename detail::signalN<boost::function_traits<Signature>::arity, + Signature, Combiner, Group, GroupCompare, SlotFunction, ExtendedSlotFunction, Mutex>::type base_type; + public: + signal(const Combiner &combiner_arg = Combiner(), const GroupCompare &group_compare = GroupCompare()): + base_type(combiner_arg, group_compare) + {} +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && BOOST_WORKAROUND(BOOST_MSVC, < 1800) + signal(signal && other) : base_type(std::move(other)) {} + signal & operator=(signal && other) { base_type::operator=(std::move(other)); return *this; } +#endif + }; + } +} + +#endif // BOOST_SIGNALS2_PREPROCESSED_SIGNAL_HPP diff --git a/3rdParty/Boost/src/boost/signals2/preprocessed_slot.hpp b/3rdParty/Boost/src/boost/signals2/preprocessed_slot.hpp new file mode 100644 index 0000000..322b1a1 --- /dev/null +++ b/3rdParty/Boost/src/boost/signals2/preprocessed_slot.hpp @@ -0,0 +1,72 @@ +// 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_SLOT_HPP +#define BOOST_SIGNALS2_PREPROCESSED_SLOT_HPP + +#include <boost/preprocessor/repetition.hpp> +#include <boost/signals2/detail/preprocessed_arg_type.hpp> +#include <boost/type_traits/function_traits.hpp> + +#ifndef BOOST_SIGNALS2_SLOT_MAX_BINDING_ARGS +#define BOOST_SIGNALS2_SLOT_MAX_BINDING_ARGS 10 +#endif + + +// template<typename Func, typename BindArgT0, typename BindArgT1, ..., typename BindArgTN-1> slotN(... +#define BOOST_SIGNALS2_SLOT_N_BINDING_CONSTRUCTOR(z, n, data) \ + template<typename Func, BOOST_SIGNALS2_PREFIXED_ARGS_TEMPLATE_DECL(n, BindArg)> \ + BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)( \ + const Func &func, BOOST_SIGNALS2_PREFIXED_FULL_REF_ARGS(n, const BindArg)) \ + { \ + init_slot_function(boost::bind(func, BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(n))); \ + } +#define BOOST_SIGNALS2_SLOT_N_BINDING_CONSTRUCTORS \ + BOOST_PP_REPEAT_FROM_TO(1, BOOST_SIGNALS2_SLOT_MAX_BINDING_ARGS, BOOST_SIGNALS2_SLOT_N_BINDING_CONSTRUCTOR, ~) + + +#define BOOST_PP_ITERATION_LIMITS (0, BOOST_PP_INC(BOOST_SIGNALS2_MAX_ARGS)) +#define BOOST_PP_FILENAME_1 <boost/signals2/detail/slot_template.hpp> +#include BOOST_PP_ITERATE() + +#undef BOOST_SIGNALS2_SLOT_N_BINDING_CONSTRUCTOR +#undef BOOST_SIGNALS2_SLOT_N_BINDING_CONSTRUCTORS + +namespace boost +{ + namespace signals2 + { + template<typename Signature, + typename SlotFunction = boost::function<Signature> > + class slot: public detail::slotN<function_traits<Signature>::arity, + Signature, SlotFunction>::type + { + private: + typedef typename detail::slotN<boost::function_traits<Signature>::arity, + Signature, SlotFunction>::type base_type; + public: + template<typename F> + slot(const F& f): base_type(f) + {} + // bind syntactic sugar +// template<typename F, typename BindArgT0, typename BindArgT1, ..., typename BindArgTn-1> slot(... +#define BOOST_SIGNALS2_SLOT_BINDING_CONSTRUCTOR(z, n, data) \ + template<typename Func, BOOST_SIGNALS2_PREFIXED_ARGS_TEMPLATE_DECL(n, BindArg)> \ + slot(const Func &func, BOOST_SIGNALS2_PREFIXED_FULL_REF_ARGS(n, const BindArg)): \ + base_type(func, BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(n)) \ + {} + BOOST_PP_REPEAT_FROM_TO(1, BOOST_SIGNALS2_SLOT_MAX_BINDING_ARGS, BOOST_SIGNALS2_SLOT_BINDING_CONSTRUCTOR, ~) +#undef BOOST_SIGNALS2_SLOT_BINDING_CONSTRUCTOR + }; + } // namespace signals2 +} + +#endif // BOOST_SIGNALS2_PREPROCESSED_SLOT_HPP diff --git a/3rdParty/Boost/src/boost/signals2/shared_connection_block.hpp b/3rdParty/Boost/src/boost/signals2/shared_connection_block.hpp new file mode 100644 index 0000000..c16bf9b --- /dev/null +++ b/3rdParty/Boost/src/boost/signals2/shared_connection_block.hpp @@ -0,0 +1,64 @@ +// 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_SHARED_CONNECTION_BLOCK_HPP +#define BOOST_SIGNALS2_SHARED_CONNECTION_BLOCK_HPP + +#include <boost/shared_ptr.hpp> +#include <boost/signals2/connection.hpp> +#include <boost/weak_ptr.hpp> + +namespace boost +{ + namespace signals2 + { + class shared_connection_block + { + public: + shared_connection_block(const signals2::connection &conn = signals2::connection(), + bool initially_blocked = true): + _weak_connection_body(conn._weak_connection_body) + { + if(initially_blocked) block(); + } + void block() + { + if(blocking()) return; + boost::shared_ptr<detail::connection_body_base> connection_body(_weak_connection_body.lock()); + if(connection_body == 0) + { + // Make _blocker non-empty so the blocking() method still returns the correct value + // after the connection has expired. + _blocker.reset(static_cast<int*>(0)); + return; + } + _blocker = connection_body->get_blocker(); + } + void unblock() + { + _blocker.reset(); + } + bool blocking() const + { + shared_ptr<void> empty; + return _blocker < empty || empty < _blocker; + } + signals2::connection connection() const + { + return signals2::connection(_weak_connection_body); + } + private: + boost::weak_ptr<detail::connection_body_base> _weak_connection_body; + shared_ptr<void> _blocker; + }; + } +} // end namespace boost + +#endif // BOOST_SIGNALS2_SHARED_CONNECTION_BLOCK_HPP diff --git a/3rdParty/Boost/src/boost/signals2/signal.hpp b/3rdParty/Boost/src/boost/signals2/signal.hpp new file mode 100644 index 0000000..c04c9e6 --- /dev/null +++ b/3rdParty/Boost/src/boost/signals2/signal.hpp @@ -0,0 +1,62 @@ +// A thread-safe version of Boost.Signals. + +// 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_SIGNAL_HPP +#define BOOST_SIGNALS2_SIGNAL_HPP + +#include <algorithm> +#include <boost/assert.hpp> +#include <boost/config.hpp> +#include <boost/function.hpp> +#include <boost/mpl/identity.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/signals2/connection.hpp> +#include <boost/signals2/detail/unique_lock.hpp> +#include <boost/signals2/detail/replace_slot_function.hpp> +#include <boost/signals2/detail/result_type_wrapper.hpp> +#include <boost/signals2/detail/signals_common.hpp> +#include <boost/signals2/detail/signals_common_macros.hpp> +#include <boost/signals2/detail/slot_groups.hpp> +#include <boost/signals2/detail/slot_call_iterator.hpp> +#include <boost/signals2/optional_last_value.hpp> +#include <boost/signals2/mutex.hpp> +#include <boost/signals2/slot.hpp> +#include <boost/throw_exception.hpp> +#include <functional> + +#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES +#include <boost/signals2/preprocessed_signal.hpp> +#else +#include <boost/signals2/variadic_signal.hpp> +#endif + +namespace boost +{ + namespace signals2 + { + // free swap function, findable by ADL + template<typename Signature, + typename Combiner, + typename Group, + typename GroupCompare, + typename SlotFunction, + typename ExtendedSlotFunction, + typename Mutex> + void swap( + signal<Signature, Combiner, Group, GroupCompare, SlotFunction, ExtendedSlotFunction, Mutex> &sig1, + signal<Signature, Combiner, Group, GroupCompare, SlotFunction, ExtendedSlotFunction, Mutex> &sig2) + { + sig1.swap(sig2); + } + } +} + +#endif // BOOST_SIGNALS2_SIGNAL_HPP diff --git a/3rdParty/Boost/src/boost/signals2/signal_base.hpp b/3rdParty/Boost/src/boost/signals2/signal_base.hpp new file mode 100644 index 0000000..05b6b5f --- /dev/null +++ b/3rdParty/Boost/src/boost/signals2/signal_base.hpp @@ -0,0 +1,33 @@ +// 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_SIGNAL_BASE_HPP +#define BOOST_SIGNALS2_SIGNAL_BASE_HPP + +#include <boost/noncopyable.hpp> +#include <boost/shared_ptr.hpp> + +namespace boost { + namespace signals2 { + class slot_base; + + class signal_base : public noncopyable + { + public: + friend class slot_base; + + virtual ~signal_base() {} + protected: + virtual shared_ptr<void> lock_pimpl() const = 0; + }; + } // end namespace signals2 +} // end namespace boost + +#endif // BOOST_SIGNALS2_SIGNAL_BASE_HPP diff --git a/3rdParty/Boost/src/boost/signals2/signal_type.hpp b/3rdParty/Boost/src/boost/signals2/signal_type.hpp new file mode 100644 index 0000000..4de5396 --- /dev/null +++ b/3rdParty/Boost/src/boost/signals2/signal_type.hpp @@ -0,0 +1,144 @@ +/* + A meta function which supports using named template type parameters + via Boost.Parameter to specify the template type parameters for + the boost::signals2::signal class. + + Author: Frank Mori Hess <fmhess@users.sourceforge.net> + Begin: 2009-01-22 +*/ +// 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_SIGNAL_TYPE_HPP +#define BOOST_SIGNALS2_SIGNAL_TYPE_HPP + +// support for function types is currently broken in Boost.Parameter +// #define BOOST_SIGNALS2_NAMED_SIGNATURE_PARAMETER + +#include <boost/signals2/signal.hpp> + +#if !defined(BOOST_PARAMETER_MAX_ARITY) +#define BOOST_PARAMETER_MAX_ARITY 7 +#else +#if BOOST_PARAMETER_MAX_ARITY < 7 +#error This header requires BOOST_PARAMETER_MAX_ARITY to be defined as 7 or greater prior to including Boost.Parameter headers +#endif // BOOST_PARAMETER_MAX_ARITY < 7 +#endif // !defined(BOOST_PARAMETER_MAX_ARITY) +#include <boost/parameter.hpp> + +#include <boost/type_traits/is_function.hpp> + +namespace boost +{ + namespace signals2 + { + namespace keywords + { +#ifdef BOOST_SIGNALS2_NAMED_SIGNATURE_PARAMETER + BOOST_PARAMETER_TEMPLATE_KEYWORD(signature_type) +#endif + BOOST_PARAMETER_TEMPLATE_KEYWORD(combiner_type) + BOOST_PARAMETER_TEMPLATE_KEYWORD(group_type) + BOOST_PARAMETER_TEMPLATE_KEYWORD(group_compare_type) + BOOST_PARAMETER_TEMPLATE_KEYWORD(slot_function_type) + BOOST_PARAMETER_TEMPLATE_KEYWORD(extended_slot_function_type) + BOOST_PARAMETER_TEMPLATE_KEYWORD(mutex_type) + } // namespace keywords + + template < +#ifdef BOOST_SIGNALS2_NAMED_SIGNATURE_PARAMETER + typename A0, +#else + typename Signature, +#endif + typename A1 = parameter::void_, + typename A2 = parameter::void_, + typename A3 = parameter::void_, + typename A4 = parameter::void_, + typename A5 = parameter::void_, + typename A6 = parameter::void_ + > + class signal_type + { + typedef parameter::parameters< +#ifdef BOOST_SIGNALS2_NAMED_SIGNATURE_PARAMETER + parameter::required<keywords::tag::signature_type, is_function<boost::mpl::_> >, +#endif + parameter::optional<keywords::tag::combiner_type>, + parameter::optional<keywords::tag::group_type>, + parameter::optional<keywords::tag::group_compare_type>, + parameter::optional<keywords::tag::slot_function_type>, + parameter::optional<keywords::tag::extended_slot_function_type>, + parameter::optional<keywords::tag::mutex_type> + > parameter_spec; + + public: + // ArgumentPack + typedef typename + parameter_spec::bind< +#ifdef BOOST_SIGNALS2_NAMED_SIGNATURE_PARAMETER + A0, +#endif + A1, A2, A3, A4, A5, A6>::type + args; + +#ifdef BOOST_SIGNALS2_NAMED_SIGNATURE_PARAMETER + typedef typename parameter::value_type<args, keywords::tag::signature_type>::type + signature_type; +#else + typedef Signature signature_type; +#endif + + typedef typename parameter::value_type + < + args, + keywords::tag::combiner_type, + optional_last_value + < + typename boost::function_traits<signature_type>::result_type + > + >::type combiner_type; + + typedef typename + parameter::value_type<args, keywords::tag::group_type, int>::type group_type; + + typedef typename + parameter::value_type<args, keywords::tag::group_compare_type, std::less<group_type> >::type + group_compare_type; + + typedef typename + parameter::value_type<args, keywords::tag::slot_function_type, function<signature_type> >::type + slot_function_type; + + typedef typename + parameter::value_type + < + args, + keywords::tag::extended_slot_function_type, + typename detail::extended_signature<function_traits<signature_type>::arity, signature_type>::function_type + >::type + extended_slot_function_type; + + typedef typename + parameter::value_type<args, keywords::tag::mutex_type, mutex>::type mutex_type; + + typedef signal + < + signature_type, + combiner_type, + group_type, + group_compare_type, + slot_function_type, + extended_slot_function_type, + mutex_type + > type; + }; + } // namespace signals2 +} // namespace boost + +#endif // BOOST_SIGNALS2_SIGNAL_TYPE_HPP diff --git a/3rdParty/Boost/src/boost/signals2/slot.hpp b/3rdParty/Boost/src/boost/signals2/slot.hpp new file mode 100644 index 0000000..b6ec4d7 --- /dev/null +++ b/3rdParty/Boost/src/boost/signals2/slot.hpp @@ -0,0 +1,33 @@ +// Boost.Signals2 library + +// 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_SLOT_HPP +#define BOOST_SIGNALS2_SLOT_HPP + +#include <boost/bind.hpp> +#include <boost/config.hpp> +#include <boost/function.hpp> +#include <boost/mpl/identity.hpp> +#include <boost/ref.hpp> +#include <boost/signals2/detail/signals_common.hpp> +#include <boost/signals2/detail/signals_common_macros.hpp> +#include <boost/signals2/detail/tracked_objects_visitor.hpp> +#include <boost/signals2/slot_base.hpp> +#include <boost/visit_each.hpp> +#include <boost/weak_ptr.hpp> + +#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES +#include <boost/signals2/preprocessed_slot.hpp> +#else +#include <boost/signals2/variadic_slot.hpp> +#endif + +#endif // BOOST_SIGNALS2_SLOT_HPP diff --git a/3rdParty/Boost/src/boost/signals2/slot_base.hpp b/3rdParty/Boost/src/boost/signals2/slot_base.hpp new file mode 100644 index 0000000..d2dd946 --- /dev/null +++ b/3rdParty/Boost/src/boost/signals2/slot_base.hpp @@ -0,0 +1,100 @@ +// 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_SLOT_BASE_HPP +#define BOOST_SIGNALS2_SLOT_BASE_HPP + +#include <boost/shared_ptr.hpp> +#include <boost/weak_ptr.hpp> +#include <boost/signals2/detail/foreign_ptr.hpp> +#include <boost/signals2/expired_slot.hpp> +#include <boost/signals2/signal_base.hpp> +#include <boost/throw_exception.hpp> +#include <boost/variant/apply_visitor.hpp> +#include <boost/variant/variant.hpp> +#include <vector> + +namespace boost +{ + namespace signals2 + { + namespace detail + { + class tracked_objects_visitor; + + typedef boost::variant<boost::weak_ptr<void>, detail::foreign_void_weak_ptr > void_weak_ptr_variant; + typedef boost::variant<boost::shared_ptr<void>, detail::foreign_void_shared_ptr > void_shared_ptr_variant; + class lock_weak_ptr_visitor + { + public: + typedef void_shared_ptr_variant result_type; + template<typename WeakPtr> + result_type operator()(const WeakPtr &wp) const + { + return wp.lock(); + } + }; + class expired_weak_ptr_visitor + { + public: + typedef bool result_type; + template<typename WeakPtr> + bool operator()(const WeakPtr &wp) const + { + return wp.expired(); + } + }; + } + + class slot_base + { + public: + typedef std::vector<detail::void_weak_ptr_variant> tracked_container_type; + typedef std::vector<detail::void_shared_ptr_variant> locked_container_type; + + const tracked_container_type& tracked_objects() const {return _tracked_objects;} + locked_container_type lock() const + { + locked_container_type locked_objects; + tracked_container_type::const_iterator it; + for(it = tracked_objects().begin(); it != tracked_objects().end(); ++it) + { + locked_objects.push_back(apply_visitor(detail::lock_weak_ptr_visitor(), *it)); + if(apply_visitor(detail::expired_weak_ptr_visitor(), *it)) + { + boost::throw_exception(expired_slot()); + } + } + return locked_objects; + } + bool expired() const + { + tracked_container_type::const_iterator it; + for(it = tracked_objects().begin(); it != tracked_objects().end(); ++it) + { + if(apply_visitor(detail::expired_weak_ptr_visitor(), *it)) return true; + } + return false; + } + protected: + friend class detail::tracked_objects_visitor; + + void track_signal(const signal_base &signal) + { + _tracked_objects.push_back(signal.lock_pimpl()); + } + + tracked_container_type _tracked_objects; + }; + } +} // end namespace boost + +#endif // BOOST_SIGNALS2_SLOT_BASE_HPP diff --git a/3rdParty/Boost/src/boost/signals2/trackable.hpp b/3rdParty/Boost/src/boost/signals2/trackable.hpp new file mode 100644 index 0000000..d6a6014 --- /dev/null +++ b/3rdParty/Boost/src/boost/signals2/trackable.hpp @@ -0,0 +1,49 @@ +// 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) + +// Compatibility class to ease porting from the original +// Boost.Signals library. However, +// boost::signals2::trackable is NOT thread-safe. + +// For more information, see http://www.boost.org + +#ifndef BOOST_SIGNALS2_TRACKABLE_HPP +#define BOOST_SIGNALS2_TRACKABLE_HPP + +#include <boost/assert.hpp> +#include <boost/shared_ptr.hpp> + +namespace boost { + namespace signals2 { + namespace detail + { + class tracked_objects_visitor; + } + class trackable { + protected: + trackable(): _tracked_ptr(static_cast<int*>(0)) {} + trackable(const trackable &): _tracked_ptr(static_cast<int*>(0)) {} + trackable& operator=(const trackable &) + { + return *this; + } + ~trackable() {} + private: + friend class detail::tracked_objects_visitor; + const shared_ptr<void>& get_shared_ptr() const + { + return _tracked_ptr; + } + + shared_ptr<void> _tracked_ptr; + }; + } // end namespace signals2 +} // end namespace boost + +#endif // BOOST_SIGNALS2_TRACKABLE_HPP diff --git a/3rdParty/Boost/src/boost/signals2/variadic_signal.hpp b/3rdParty/Boost/src/boost/signals2/variadic_signal.hpp new file mode 100644 index 0000000..d7d2619 --- /dev/null +++ b/3rdParty/Boost/src/boost/signals2/variadic_signal.hpp @@ -0,0 +1,44 @@ +/* + A variadic implementation of variadic boost::signals2::signal, used when variadic + template support is detected in the compiler. + + Author: Frank Mori Hess <fmhess@users.sourceforge.net> + Begin: 2009-05-26 +*/ +// 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_VARIADIC_SIGNAL_HPP +#define BOOST_SIGNALS2_VARIADIC_SIGNAL_HPP + +#include <boost/preprocessor/control/expr_if.hpp> +#include <boost/signals2/detail/variadic_arg_type.hpp> +#include <boost/signals2/detail/variadic_slot_invoker.hpp> +#include <boost/type_traits/function_traits.hpp> + +namespace boost +{ + namespace signals2 + { + namespace detail + { + template<typename Signature> class variadic_extended_signature; + // partial template specialization + template<typename R, typename ... Args> + class variadic_extended_signature<R (Args...)> + { + public: + typedef boost::function<R (const boost::signals2::connection &, Args...)> function_type; + }; + } // namespace detail + } // namespace signals2 +} // namespace boost + +#include <boost/signals2/detail/signal_template.hpp> + +#endif // BOOST_SIGNALS2_VARIADIC_SIGNAL_HPP diff --git a/3rdParty/Boost/src/boost/signals2/variadic_slot.hpp b/3rdParty/Boost/src/boost/signals2/variadic_slot.hpp new file mode 100644 index 0000000..59ae176 --- /dev/null +++ b/3rdParty/Boost/src/boost/signals2/variadic_slot.hpp @@ -0,0 +1,25 @@ +// Boost.Signals2 library + +// Copyright Frank Mori Hess 2009. +// +// 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_VARIADIC_SLOT_HPP +#define BOOST_SIGNALS2_VARIADIC_SLOT_HPP + +#include <boost/signals2/detail/variadic_arg_type.hpp> + +#define BOOST_SIGNALS2_SLOT_N_BINDING_CONSTRUCTORS \ + template<typename A1, typename A2, typename ... BindArgs> \ + slot(const A1 &arg1, const A2 &arg2, const BindArgs & ... args) \ + { \ + init_slot_function(boost::bind(arg1, arg2, args...)); \ + } + + +#include <boost/signals2/detail/slot_template.hpp> +#endif // BOOST_SIGNALS2_VARIADIC_SLOT_HPP |