// $Id$ // // Copyright (C) 2009 // Fraunhofer Institute for Open Communication Systems (FOKUS) // Competence Center NETwork research (NET), St. Augustin, GERMANY // Stefan Bund // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the // Free Software Foundation, Inc., // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. /** \file \brief MultiConnectorMixin Boost.Preprocesser external iteration include */ #if !BOOST_PP_IS_ITERATING && !defined(MPP_SENF_PPI_MultiConnectorMixin_) #define MPP_SENF_PPI_MultiConnectorMixin_ 1 // Custom includes #include #include #include #include #include #include #include #include #include #include #include // ///////////////////////////mpp.p//////////////////////////////////////// #elif BOOST_PP_IS_ITERATING // //////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////// // Local Macros #define mpp_TplParams() \ BOOST_PP_IF( \ BOOST_PP_ITERATION(), \ mpp_TplParams_, \ BOOST_PP_EMPTY)() #define mpp_TplParams_() \ template #define mpp_TplParamsKomma() \ BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), class A) #define mpp_FnParams() \ BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), A, const & a) #define mpp_FnParamsKomma() \ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(BOOST_PP_ITERATION(), A, const & a) #define mpp_CallParams() \ BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), a) #define mpp_CallParamsKomma() \ BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), a) // Same as above but for outer loop in nested loops #define mpp_TplParamsKomma2() \ BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_FRAME_ITERATION(1), class B) #define mpp_FnParams2() \ BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_FRAME_ITERATION(1), B, const & a) #define mpp_FnParamsKomma2() \ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(BOOST_PP_FRAME_ITERATION(1), B, const & b) #define mpp_CallParams2() \ BOOST_PP_ENUM_PARAMS(BOOST_PP_FRAME_ITERATION(1), b) #define mpp_CallParamsKomma2() \ BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_FRAME_ITERATION(1), b) // //////////////////////////////////////////////////////////////////////// #if BOOST_PP_ITERATION_FLAGS()==1 // ////////////////////////////////////// // //////////////////////////////////////////////////////////////////////// // MultiConnectorMixin member declaration mpp_TplParams() ConnectorType_ & newConnector( mpp_FnParams() ); // //////////////////////////////////////////////////////////////////////// #elif BOOST_PP_ITERATION_FLAGS()==9 // ////////////////////////////////////// // //////////////////////////////////////////////////////////////////////// // MultiConnectorMixin member declaration template static std::pair connect_(Source & source, Target & target mpp_FnParamsKomma()); // //////////////////////////////////////////////////////////////////////// #elif BOOST_PP_ITERATION_FLAGS()==2 // //////////////////////////////////// // //////////////////////////////////////////////////////////////////////// // senf::ppi namespace member declaration // Here the reference to Source::ConnectorType / Target::ConnectorType // works like enable_if, since only MultiConnector modules have those members template typename boost::enable_if< boost::mpl::and_< senf::ppi::module::detail::is_multiconnector_source, boost::mpl::not_< senf::ppi::module::detail::is_multiconnector_target > >, typename Source::ConnectorType & >::type connect(Source & source, Target & target mpp_FnParamsKomma()); template typename boost::enable_if< boost::mpl::and_< boost::mpl::not_< senf::ppi::module::detail::is_multiconnector_source >, senf::ppi::module::detail::is_multiconnector_target >, typename Target::ConnectorType & >::type connect(Source & source, Target & target mpp_FnParamsKomma()); #define BOOST_PP_ITERATION_PARAMS_2 (4, (\ 0, \ SENF_MULTI_CONNECTOR_MAX_ARGS, \ SENF_ABSOLUTE_INCLUDE_PATH(PPI/MultiConnectorMixin.mpp), \ 4 )) #include BOOST_PP_ITERATE() // //////////////////////////////////////////////////////////////////////// #elif BOOST_PP_ITERATION_FLAGS()==6 // //////////////////////////////////// // //////////////////////////////////////////////////////////////////////// // senf::ppi namespace member declaration (nested) template typename boost::enable_if< boost::mpl::and_< boost::is_base_of, boost::is_base_of >, std::pair >::type connect(Source & source, Target & target mpp_FnParamsKomma()); // //////////////////////////////////////////////////////////////////////// #elif BOOST_PP_ITERATION_FLAGS()==4 // //////////////////////////////////// // //////////////////////////////////////////////////////////////////////// // senf::ppi::detail namespace member declaration (nested iteration) namespace detail { template typename boost::enable_if_c< senf::function_arity::value == BOOST_PP_ITERATION()+1, std::pair >::type connect_(Fn, Source & source, Target & target mpp_FnParamsKomma() mpp_FnParamsKomma2()); } // //////////////////////////////////////////////////////////////////////// #elif BOOST_PP_ITERATION_FLAGS()==3 // //////////////////////////////////// // //////////////////////////////////////////////////////////////////////// // Implementation //////////////////////////////////////// // Map container template mpp_TplParams() prefix_ ConnectorType_ & senf::ppi::module::MultiConnectorMixin:: newConnector(mpp_FnParams()) { std::auto_ptr conn (new ConnectorType_); KeyType_ key (static_cast(this)->connectorSetup(*conn mpp_CallParamsKomma())); return * connectors_.insert(key, conn).first->second; } //////////////////////////////////////// // Vector container template mpp_TplParams() prefix_ ConnectorType_ & senf::ppi::module::MultiConnectorMixin:: newConnector(mpp_FnParams()) { connectors_.push_back(new ConnectorType_); ConnectorType_ & conn (connectors_.back()); try { static_cast(this)->connectorSetup(conn mpp_CallParamsKomma()); } catch (...) { connectors_.pop_back(); throw; } return conn; } //////////////////////////////////////// // User managed container template mpp_TplParams() prefix_ ConnectorType_ & senf::ppi::module::MultiConnectorMixin:: newConnector(mpp_FnParams()) { std::auto_ptr cp (new ConnectorType_); ConnectorType_ & cref (*cp); static_cast(this)->connectorSetup(cp mpp_CallParamsKomma()); return cref; } //////////////////////////////////////// // senf::ppi::module::detail::MultiConnectorMixinAccess members template typename Module::ConnectorType & senf::ppi::module::detail::MultiConnectorMixinAccess::newConnector( Module & module mpp_FnParamsKomma()) { return module.newConnector(mpp_CallParams()); } template std::pair senf::ppi::module::detail::MultiConnectorMixinAccess::connect( Source & source, Target & target mpp_FnParamsKomma()) { return Source::connect_(source, target mpp_CallParamsKomma()); } //////////////////////////////////////// // senf::ppi::connect template typename boost::enable_if< boost::mpl::and_< senf::ppi::module::detail::is_multiconnector_source, boost::mpl::not_< senf::ppi::module::detail::is_multiconnector_target > >, typename Source::ConnectorType & >::type senf::ppi::connect(Source & source, Target & target mpp_FnParamsKomma()) { typename Source::ConnectorType & c ( module::detail::MultiConnectorMixinAccess::newConnector(source mpp_CallParamsKomma())); connect(c, target); return c; } template typename boost::enable_if< boost::mpl::and_< boost::mpl::not_< senf::ppi::module::detail::is_multiconnector_source >, senf::ppi::module::detail::is_multiconnector_target >, typename Target::ConnectorType & >::type senf::ppi::connect(Source & source, Target & target mpp_FnParamsKomma()) { typename Target::ConnectorType & c ( module::detail::MultiConnectorMixinAccess::newConnector(target mpp_CallParamsKomma())); connect(source, c); return c; } #define BOOST_PP_ITERATION_PARAMS_2 (4, (\ 0, \ SENF_MULTI_CONNECTOR_MAX_ARGS, \ SENF_ABSOLUTE_INCLUDE_PATH(PPI/MultiConnectorMixin.mpp), \ 5 )) #include BOOST_PP_ITERATE() // //////////////////////////////////////////////////////////////////////// #elif BOOST_PP_ITERATION_FLAGS()==5 // //////////////////////////////////// // //////////////////////////////////////////////////////////////////////// // Implementation for nested iteration template typename boost::enable_if_c< senf::function_arity::value == BOOST_PP_ITERATION()+1, std::pair >::type senf::ppi::detail::connect_(Fn, Source & source, Target & target mpp_FnParamsKomma() mpp_FnParamsKomma2()) { typename Source::ConnectorType & s ( module::detail::MultiConnectorMixinAccess::newConnector(source mpp_CallParamsKomma())); typename Target::ConnectorType & t ( module::detail::MultiConnectorMixinAccess::newConnector(target mpp_CallParamsKomma2())); connect(s,t); return std::pair(s,t); } // //////////////////////////////////////////////////////////////////////// #elif BOOST_PP_ITERATION_FLAGS()==7 // //////////////////////////////////// // //////////////////////////////////////////////////////////////////////// // Implementation template template std::pair senf::ppi::module::MultiConnectorMixin:: connect_(Source & source, Target & target mpp_FnParamsKomma()) { return senf::ppi::detail::connect_( & Self_::connectorSetup, source, target mpp_CallParamsKomma()); } template template std::pair senf::ppi::module::MultiConnectorMixin:: connect_(Source & source, Target & target mpp_FnParamsKomma()) { return senf::ppi::detail::connect_( & Self_::connectorSetup, source, target mpp_CallParamsKomma()); } template template std::pair senf::ppi::module::MultiConnectorMixin:: connect_(Source & source, Target & target mpp_FnParamsKomma()) { return senf::ppi::detail::connect_( & Self_::connectorSetup, source, target mpp_CallParamsKomma()); } template typename boost::enable_if< boost::mpl::and_< boost::is_base_of, boost::is_base_of >, std::pair >::type senf::ppi::connect(Source & source, Target & target mpp_FnParamsKomma()) { return module::detail::MultiConnectorMixinAccess::connect( source, target mpp_CallParamsKomma()); } // //////////////////////////////////////////////////////////////////////// #elif BOOST_PP_ITERATION_FLAGS()==8 // //////////////////////////////////// // //////////////////////////////////////////////////////////////////////// // senf::ppi::module::detail::MultiConnectorMixinAccess members template static typename Module::ConnectorType & newConnector(Module & module mpp_FnParamsKomma()); template static std::pair connect(Source & source, Target & target mpp_FnParamsKomma()); // //////////////////////////////////////////////////////////////////////// #endif // ///////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////// // Undefine local Macros #undef mpp_CallParamsKomma2 #undef mpp_CallParams2 #undef mpp_FnParamsKomma2 #undef mpp_FnParams2 #undef mpp_TplParamsKomma2 #undef mpp_CallParamsKomma #undef mpp_CallParams #undef mpp_FnParamsKomma #undef mpp_FnParams #undef mpp_TplParamsKomma #undef mpp_TplParams_ #undef mpp_TplParams // //////////////////////////////////////////////////////////////////////// /* (save-excursion (re-search-backward "^// Undefine local Macros") (forward-line 1) (delete-region (point) (progn (search-forward "// ////") (forward-line -1) (point))) (insert "\n") (let ((b (point)) (e (progn (insert (save-excursion (re-search-backward "^// Local Macros") (search-forward "#define") (beginning-of-line) (buffer-substring (point) (progn (search-forward "// ////") (search-backward "#define") (forward-line 1) (point))))) (point)))) (reverse-region b e) (shell-command-on-region b e "grep -F '#define'" nil t) (goto-char b) (while (looking-at "#define") (delete-char 7) (insert "#undef") (skip-chars-forward " ") (re-search-forward "[^a-zA-Z0-9_]") (delete-region (1- (point)) (progn (end-of-line) (point))) (forward-line 1)))) */ // //////////////////////////////////////////////////////////////////////// #endif // ///////////////////////////////////////////////////////////////// // ///////////////////////////mpp.e//////////////////////////////////////// // Local Variables: // mode: c++ // fill-column: 100 // comment-column: 40 // c-file-style: "senf" // indent-tabs-mode: nil // ispell-local-dictionary: "american" // compile-command: "scons -u test" // End: