Search:

SENF Extensible Network Framework

  • Home
  • Download
  • Wiki
  • BerliOS
  • ChangeLog
  • Browse SVN
  • Bug Tracker
  • Overview
  • Examples
  • HowTos
  • Glossary
  • PPI
  • Packets
  • Scheduler
  • Socket
  • Utils
  • Console
  • Daemon
  • Logger
  • Termlib
  • Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • Directories
  • File List
  • File Members

MultiConnectorMixin.mpp

Go to the documentation of this file.
00001 // $Id: MultiConnectorMixin.mpp 1742 2010-11-04 14:51:56Z g0dil $
00002 //
00003 // Copyright (C) 2009
00004 // Fraunhofer (FOKUS)
00005 // Competence Center NETwork research (NET), St. Augustin, GERMANY
00006 //     Stefan Bund <g0dil@berlios.de>
00007 //
00008 // This program is free software; you can redistribute it and/or modify
00009 // it under the terms of the GNU General Public License as published by
00010 // the Free Software Foundation; either version 2 of the License, or
00011 // (at your option) any later version.
00012 //
00013 // This program is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 // GNU General Public License for more details.
00017 //
00018 // You should have received a copy of the GNU General Public License
00019 // along with this program; if not, write to the
00020 // Free Software Foundation, Inc.,
00021 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00022 
00026 #if !BOOST_PP_IS_ITERATING && !defined(MPP_SENF_PPI_MultiConnectorMixin_)
00027 #define MPP_SENF_PPI_MultiConnectorMixin_ 1
00028 
00029 // Custom includes
00030 #include <boost/preprocessor/iteration/iterate.hpp>
00031 #include <boost/preprocessor/control/if.hpp>
00032 #include <boost/preprocessor/facilities/empty.hpp>
00033 #include <boost/preprocessor/repetition/enum_params.hpp>
00034 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
00035 #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
00036 #include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
00037 #include <boost/type_traits/is_base_of.hpp>
00038 #include <boost/mpl/and.hpp>
00039 #include <boost/mpl/not.hpp>
00040 #include <boost/tuple/tuple.hpp>
00041 
00042 //-///////////////////////////mpp.p////////////////////////////////////////
00043 #elif BOOST_PP_IS_ITERATING //-
00044 //-
00045 // Local Macros
00046 
00047 // => template <class A0, class A1, ...>
00048 #define mpp_TplParams()                                                 \
00049     BOOST_PP_IF(BOOST_PP_ITERATION(), mpp_TplParams_, BOOST_PP_EMPTY)()
00050 #define mpp_TplParams_()                                                \
00051     template <BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
00052 
00053 // => , class A0, class A1, ...
00054 #define mpp_TplParamsKomma()                                            \
00055     BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), class A)
00056 
00057 // => A0 const & a0, A1 const & a1, ...
00058 #define mpp_FnParams()                                                  \
00059     BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), A, const & a)
00060 
00061 // => , A0 const & a0, A1 const & a1, ...
00062 #define mpp_FnParamsKomma()                                             \
00063     BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(BOOST_PP_ITERATION(), A, const & a)
00064 
00065 // => a0, a1, ...
00066 #define mpp_CallParams()                                                \
00067     BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), a)
00068 
00069 // => , a0, a1, ...
00070 #define mpp_CallParamsKomma()                                           \
00071     BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), a)
00072 
00073 // Same as above but for outer iteration (in nested file iteration)
00074 #define mpp_TplParamsKomma2()                                            \
00075     BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_FRAME_ITERATION(1), class B)
00076 #define mpp_FnParams2()                                                  \
00077     BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_FRAME_ITERATION(1), B, cont & b)
00078 #define mpp_FnParamsKomma2()                                             \
00079     BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(BOOST_PP_FRAME_ITERATION(1), B, const & b)
00080 #define mpp_CallParams2()                                                \
00081     BOOST_PP_ENUM_PARAMS(BOOST_PP_FRAME_ITERATION(1), b)
00082 #define mpp_CallParamsKomma2()                                           \
00083     BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_FRAME_ITERATION(1), b)
00084 
00085 //-////////////////////////////////////////////////////////////////////////
00086 #if BOOST_PP_ITERATION_FLAGS()==1 //-
00087 //-
00088 // senf::ppi::module::MultiConnectorMixin member declaration 1..MAX_ARGS
00089 
00090 mpp_TplParams()
00091 ConnectorType_ & newConnector( mpp_FnParams() );
00092 
00093 //-////////////////////////////////////////////////////////////////////////
00094 #elif BOOST_PP_ITERATION_FLAGS()==2 //-
00095 //-
00096 // senf::ppi namespace member declaration 1..MAX_ARGS
00097 
00098 // Here the reference to Source::ConnectorType / Target::ConnectorType
00099 // works like enable_if, since only MultiConnector modules have those members
00100 
00101 template <class Source, class Target mpp_TplParamsKomma()>
00102 typename boost::enable_if<
00103     boost::mpl::and_<
00104         senf::ppi::module::detail::IsMulticonnectorSource<Source>,
00105         boost::mpl::not_< senf::ppi::module::detail::IsMulticonnectorTarget<Target> > >,
00106     typename Source::ConnectorType & >::type
00107 connect(Source & source mpp_FnParamsKomma(), Target & target);
00108 
00109 template <class Source, class Target mpp_TplParamsKomma()>
00110 typename boost::enable_if<
00111     boost::mpl::and_<
00112         boost::mpl::not_< senf::ppi::module::detail::IsMulticonnectorSource<Source> >,
00113         senf::ppi::module::detail::IsMulticonnectorTarget<Target> >,
00114     typename Target::ConnectorType & >::type
00115 connect(Source & source, Target & target mpp_FnParamsKomma());
00116 
00117 #define BOOST_PP_ITERATION_PARAMS_2 (4, (\
00118         0, \
00119         SENF_MULTI_CONNECTOR_MAX_ARGS, \
00120         SENF_ABSOLUTE_INCLUDE_PATH(PPI/MultiConnectorMixin.mpp), \
00121         4 ))
00122 #include BOOST_PP_ITERATE()
00123 
00124 //-////////////////////////////////////////////////////////////////////////
00125 #elif BOOST_PP_ITERATION_FLAGS()==4 //-
00126 //-
00127 // senf::ppi namespace member declaration 1..MAX_ARGS x 1..MAX_ARGS
00128 
00129 template <class Source, class Target mpp_TplParamsKomma() mpp_TplParamsKomma2()>
00130 typename boost::enable_if<
00131     boost::mpl::and_<
00132         boost::is_base_of<connector::OutputConnector, typename Source::ConnectorType>,
00133         boost::is_base_of<connector::InputConnector, typename Target::ConnectorType> >,
00134     boost::tuple<typename Source::ConnectorType &, typename Target::ConnectorType &> >::type
00135 connect(Source & source mpp_FnParamsKomma(), Target & target mpp_FnParamsKomma2());
00136 
00137 //-////////////////////////////////////////////////////////////////////////
00138 #elif BOOST_PP_ITERATION_FLAGS()==8 //-
00139 //-
00140 // senf::ppi::module::detail::MultiConnectorMixinAccess member declaration 1..MAX_ARGS
00141 
00142 template <class Module mpp_TplParamsKomma()>
00143 static typename Module::ConnectorType &
00144 newConnector(Module & module mpp_FnParamsKomma());
00145 
00146 //-////////////////////////////////////////////////////////////////////////
00147 #elif BOOST_PP_ITERATION_FLAGS()==3 //-
00148 //-
00149 // Implementation 1..MAX_ARGS
00150 
00151 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00152 // Map container
00153 
00154 template <class Self_, class ConnectorType_, class KeyType_, class ContainerType_>
00155 mpp_TplParams()
00156 prefix_ ConnectorType_ &
00157 senf::ppi::module::MultiConnectorMixin<Self_,ConnectorType_,KeyType_,ContainerType_>::
00158 newConnector(mpp_FnParams())
00159 {
00160     std::auto_ptr<ConnectorType_> conn (new detail::MultiConnectorWrapper<Self_,ConnectorType_>);
00161     KeyType_ key (static_cast<Self_*>(this)->connectorSetup(*conn mpp_CallParamsKomma()));
00162     return * connectors_.insert(key, conn).first->second;
00163 }
00164 
00165 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00166 // Vector container
00167 
00168 template <class Self_, class ConnectorType_, class ContainerType_>
00169 mpp_TplParams()
00170 prefix_ ConnectorType_ &
00171 senf::ppi::module::MultiConnectorMixin<Self_,ConnectorType_,void,ContainerType_>::
00172 newConnector(mpp_FnParams())
00173 {
00174     connectors_.push_back(new detail::MultiConnectorWrapper<Self_,ConnectorType_>);
00175     ConnectorType_ & conn (connectors_.back());
00176     try { static_cast<Self_*>(this)->connectorSetup(conn mpp_CallParamsKomma()); }
00177     catch (...) { disconnected(conn); throw; }
00178     return conn;
00179 }
00180 
00181 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00182 // User managed container
00183 
00184 template <class Self_, class ConnectorType_>
00185 mpp_TplParams()
00186 prefix_ ConnectorType_ &
00187 senf::ppi::module::MultiConnectorMixin<Self_,ConnectorType_,void,void>::
00188 newConnector(mpp_FnParams())
00189 {
00190     std::auto_ptr<ConnectorType_> cp (new detail::MultiConnectorWrapper<Self_,ConnectorType_>);
00191     ConnectorType_ & cref (*cp);
00192     static_cast<Self_*>(this)->connectorSetup(cp mpp_CallParamsKomma());
00193     return cref;
00194 }
00195 
00196 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00197 // senf::ppi::connect
00198 
00199 template <class Source, class Target mpp_TplParamsKomma()>
00200 typename boost::enable_if<
00201     boost::mpl::and_<
00202         senf::ppi::module::detail::IsMulticonnectorSource<Source>,
00203         boost::mpl::not_< senf::ppi::module::detail::IsMulticonnectorTarget<Target> > >,
00204     typename Source::ConnectorType & >::type
00205 senf::ppi::connect(Source & source mpp_FnParamsKomma(), Target & target)
00206 {
00207     typename Source::ConnectorType & c (
00208         module::detail::MultiConnectorMixinAccess::newConnector(source mpp_CallParamsKomma()));
00209     connect(c, target);
00210     return c;
00211 }
00212 
00213 template <class Source, class Target mpp_TplParamsKomma()>
00214 typename boost::enable_if<
00215     boost::mpl::and_<
00216         boost::mpl::not_< senf::ppi::module::detail::IsMulticonnectorSource<Source> >,
00217         senf::ppi::module::detail::IsMulticonnectorTarget<Target> >,
00218     typename Target::ConnectorType & >::type
00219 senf::ppi::connect(Source & source, Target & target mpp_FnParamsKomma())
00220 {
00221     typename Target::ConnectorType & c (
00222         module::detail::MultiConnectorMixinAccess::newConnector(target mpp_CallParamsKomma()));
00223     connect(source, c);
00224     return c;
00225 }
00226 
00227 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00228 // senf::ppi::module::detail::MultiConnectorMixinAccess members
00229 
00230 template <class Module mpp_TplParamsKomma()>
00231 typename Module::ConnectorType &
00232 senf::ppi::module::detail::MultiConnectorMixinAccess::newConnector(
00233     Module & module mpp_FnParamsKomma())
00234 {
00235     return module.newConnector(mpp_CallParams());
00236 }
00237 
00238 #define BOOST_PP_ITERATION_PARAMS_2 (4, (\
00239         0, \
00240         SENF_MULTI_CONNECTOR_MAX_ARGS, \
00241         SENF_ABSOLUTE_INCLUDE_PATH(PPI/MultiConnectorMixin.mpp), \
00242         5 ))
00243 #include BOOST_PP_ITERATE()
00244 
00245 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00246 #elif BOOST_PP_ITERATION_FLAGS()==5 //-
00247 //-
00248 // Implementation 1..MAX_ARGS x 1..MAX_ARGS
00249 
00250 template <class Source, class Target mpp_TplParamsKomma() mpp_TplParamsKomma2()>
00251 typename boost::enable_if<
00252     boost::mpl::and_<
00253         boost::is_base_of<senf::ppi::connector::OutputConnector, typename Source::ConnectorType>,
00254         boost::is_base_of<senf::ppi::connector::InputConnector, typename Target::ConnectorType> >,
00255     boost::tuple<typename Source::ConnectorType &, typename Target::ConnectorType &> >::type
00256 senf::ppi::connect(Source & source mpp_FnParamsKomma(), Target & target mpp_FnParamsKomma2())
00257 {
00258     typename Source::ConnectorType & s (
00259         module::detail::MultiConnectorMixinAccess::newConnector(source mpp_CallParamsKomma()));
00260     typename Target::ConnectorType & t (
00261         module::detail::MultiConnectorMixinAccess::newConnector(target mpp_CallParamsKomma2()));
00262     connect(s,t);
00263     return boost::tie(s,t);
00264 }
00265 
00266 //-////////////////////////////////////////////////////////////////////////
00267 #endif //-
00268 //-
00269 // Undefine local Macros
00270 
00271 #undef mpp_CallParamsKomma2
00272 #undef mpp_CallParams2
00273 #undef mpp_FnParamsKomma2
00274 #undef mpp_FnParams2
00275 #undef mpp_TplParamsKomma2
00276 #undef mpp_CallParamsKomma
00277 #undef mpp_CallParams
00278 #undef mpp_FnParamsKomma
00279 #undef mpp_FnParams
00280 #undef mpp_TplParamsKomma
00281 #undef mpp_TplParams_
00282 #undef mpp_TplParams
00283 
00284 //-////////////////////////////////////////////////////////////////////////
00285 /*
00286  (save-excursion (re-search-backward "^// Undefine local Macros")
00287  (forward-line 1) (delete-region (point) (progn (search-forward
00288  "//-////") (forward-line -1) (point))) (insert "\n") (let ((b (point))
00289  (e (progn (insert (save-excursion (re-search-backward
00290  "^// Local Macros") (search-forward "#define") (beginning-of-line)
00291  (buffer-substring (point) (progn (search-forward "//-////")
00292  (search-backward "#define") (forward-line 1) (point))))) (point))))
00293  (reverse-region b e) (shell-command-on-region b e "grep -F '#define'" nil
00294  t) (goto-char b) (while (looking-at "#define") (delete-char 7) (insert
00295  "#undef") (skip-chars-forward " ") (re-search-forward "[^a-zA-Z0-9_]")
00296  (delete-region (1- (point)) (progn (end-of-line) (point))) (forward-line
00297  1))))
00298 */
00299 //-////////////////////////////////////////////////////////////////////////
00300 #endif //-
00301 //-
00302 
00303 
00304 // Local Variables:
00305 // mode: c++
00306 // fill-column: 100
00307 // comment-column: 40
00308 // c-file-style: "senf"
00309 // indent-tabs-mode: nil
00310 // ispell-local-dictionary: "american"
00311 // compile-command: "scons -u test"
00312 // End:

Contact: senf-dev@lists.berlios.de | © 2006-2010 Fraunhofer Institute for Open Communication Systems, Network Research