diff options
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 |