#ifndef SIGNAL_NETWORK_MULTICHAIN_HPP #define SIGNAL_NETWORK_MULTICHAIN_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace signals { template class multichain; namespace detail { struct connect_pair{ template< typename T > void operator()(T& t){ connect(fusion::at_c<0>(t), fusion::at_c<1>(t)); } }; template class multichain_impl : public filter_base, typename mpl::begin::type::signal_type, mpl::vector<> > { protected: typedef typename boost::function_types::parameter_types::type parameter_types; typedef typename boost::fusion::result_of::as_vector::type parameter_vector; public: typedef typename T::signal_type signal_type; typedef typename T::signature_type signature_type; typedef T proxy_producer_for; typedef typename boost::fusion::vector< T > vec_T; typedef typename boost::fusion::result_of::begin::type first; typedef typename boost::fusion::result_of::end::type last; typedef typename boost::fusion::result_of::next::type after_first; typedef typename boost::fusion::result_of::prior::type before_last; typedef typename boost::fusion::iterator_range producer_range; typedef typename boost::fusion::iterator_range consumer_range; /// Pairs of Component which should be connected typedef typename boost::fusion::vector connection_pairs; multichain_impl() { initialize(); } ~multichain_impl() { } template struct result { typedef typename boost::function_traits::result_type type; }; /// Sending a signal to the chain will forward it to the first component in the chain. typename boost::function_traits::result_type operator()(const parameter_vector &vec_par) { return boost::fusion::fused(fusion::deref(fusion::begin(components)))(vec_par); } /// The default signal coming out of the chain is the default signal of the last component in the chain. /* typename T::signal_type &default_signal() const { return components[size-1].default_signal(); }*/ typename last::signal_type &default_signal() const { return boost::dataflow::get_default_port(fusion::deref(fusion::prior(fusion::end(components)))); } private: void initialize() { first First(components); last Last(components); after_first After_First(components); before_last Before_Last(components); producer_range Producer_Range(First, Before_Last); consumer_range Consumer_Range(After_First, Last); assert( Producer_Range == fusion::pop_back( components ) ); assert( Consumer_Range == fusion::pop_front( components ) ); /// Connect the pairs of producers and consumer components. boost::fusion::for_each( boost::fusion::zip_view( connection_pairs( Producer_Range, Consumer_Range ) ), connect_pair() ); } vec_T components; }; } /** \brief Connects a number of components of different types in a chain. \param T Type of the component. \param Signature Signature of the signal sent and received. */ template class multichain : public boost::fusion::unfused_inherited, typename boost::function_types::parameter_types::type > { protected: typedef boost::fusion::unfused_inherited, typename boost::function_types::parameter_types::type > base_type; public: multichain() : base_type() {} }; } } // namespace boost::signals #endif // SIGNAL_NETWORK_MULTICHAIN_HPP