Fix documentation build under maverick (doxygen 1.7.1)
[senf.git] / senf / PPI / MultiConnectorMixin.mpp
1 // $Id$
2 //
3 // Copyright (C) 2009
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief MultiConnectorMixin Boost.Preprocesser external iteration include */
25
26 #if !BOOST_PP_IS_ITERATING && !defined(MPP_SENF_PPI_MultiConnectorMixin_)
27 #define MPP_SENF_PPI_MultiConnectorMixin_ 1
28
29 // Custom includes
30 #include <boost/preprocessor/iteration/iterate.hpp>
31 #include <boost/preprocessor/control/if.hpp>
32 #include <boost/preprocessor/facilities/empty.hpp>
33 #include <boost/preprocessor/repetition/enum_params.hpp>
34 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
35 #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
36 #include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
37 #include <boost/type_traits/is_base_of.hpp>
38 #include <boost/mpl/and.hpp>
39 #include <boost/mpl/not.hpp>
40 #include <boost/tuple/tuple.hpp>
41
42 //-///////////////////////////mpp.p////////////////////////////////////////
43 #elif BOOST_PP_IS_ITERATING //-////////////////////////////////////////////
44 //-////////////////////////////////////////////////////////////////////////
45 // Local Macros
46
47 // => template <class A0, class A1, ...>
48 #define mpp_TplParams()                                                 \
49     BOOST_PP_IF(BOOST_PP_ITERATION(), mpp_TplParams_, BOOST_PP_EMPTY)()
50 #define mpp_TplParams_()                                                \
51     template <BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
52
53 // => , class A0, class A1, ...
54 #define mpp_TplParamsKomma()                                            \
55     BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), class A)
56
57 // => A0 const & a0, A1 const & a1, ...
58 #define mpp_FnParams()                                                  \
59     BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), A, const & a)
60
61 // => , A0 const & a0, A1 const & a1, ...
62 #define mpp_FnParamsKomma()                                             \
63     BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(BOOST_PP_ITERATION(), A, const & a)
64
65 // => a0, a1, ...
66 #define mpp_CallParams()                                                \
67     BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), a)
68
69 // => , a0, a1, ...
70 #define mpp_CallParamsKomma()                                           \
71     BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), a)
72
73 // Same as above but for outer iteration (in nested file iteration)
74 #define mpp_TplParamsKomma2()                                            \
75     BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_FRAME_ITERATION(1), class B)
76 #define mpp_FnParams2()                                                  \
77     BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_FRAME_ITERATION(1), B, cont & b)
78 #define mpp_FnParamsKomma2()                                             \
79     BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(BOOST_PP_FRAME_ITERATION(1), B, const & b)
80 #define mpp_CallParams2()                                                \
81     BOOST_PP_ENUM_PARAMS(BOOST_PP_FRAME_ITERATION(1), b)
82 #define mpp_CallParamsKomma2()                                           \
83     BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_FRAME_ITERATION(1), b)
84
85 //-////////////////////////////////////////////////////////////////////////
86 #if BOOST_PP_ITERATION_FLAGS()==1 //-//////////////////////////////////////
87 //-////////////////////////////////////////////////////////////////////////
88 // senf::ppi::module::MultiConnectorMixin member declaration 1..MAX_ARGS
89
90 mpp_TplParams()
91 ConnectorType_ & newConnector( mpp_FnParams() );
92
93 //-////////////////////////////////////////////////////////////////////////
94 #elif BOOST_PP_ITERATION_FLAGS()==2 //-////////////////////////////////////
95 //-////////////////////////////////////////////////////////////////////////
96 // senf::ppi namespace member declaration 1..MAX_ARGS
97
98 // Here the reference to Source::ConnectorType / Target::ConnectorType
99 // works like enable_if, since only MultiConnector modules have those members
100
101 template <class Source, class Target mpp_TplParamsKomma()>
102 typename boost::enable_if<
103     boost::mpl::and_<
104         senf::ppi::module::detail::IsMulticonnectorSource<Source>,
105         boost::mpl::not_< senf::ppi::module::detail::IsMulticonnectorTarget<Target> > >,
106     typename Source::ConnectorType & >::type
107 connect(Source & source mpp_FnParamsKomma(), Target & target);
108
109 template <class Source, class Target mpp_TplParamsKomma()>
110 typename boost::enable_if<
111     boost::mpl::and_<
112         boost::mpl::not_< senf::ppi::module::detail::IsMulticonnectorSource<Source> >,
113         senf::ppi::module::detail::IsMulticonnectorTarget<Target> >,
114     typename Target::ConnectorType & >::type
115 connect(Source & source, Target & target mpp_FnParamsKomma());
116
117 #define BOOST_PP_ITERATION_PARAMS_2 (4, (\
118         0, \
119         SENF_MULTI_CONNECTOR_MAX_ARGS, \
120         SENF_ABSOLUTE_INCLUDE_PATH(PPI/MultiConnectorMixin.mpp), \
121         4 ))
122 #include BOOST_PP_ITERATE()
123
124 //-////////////////////////////////////////////////////////////////////////
125 #elif BOOST_PP_ITERATION_FLAGS()==4 //-////////////////////////////////////
126 //-////////////////////////////////////////////////////////////////////////
127 // senf::ppi namespace member declaration 1..MAX_ARGS x 1..MAX_ARGS
128
129 template <class Source, class Target mpp_TplParamsKomma() mpp_TplParamsKomma2()>
130 typename boost::enable_if<
131     boost::mpl::and_<
132         boost::is_base_of<connector::OutputConnector, typename Source::ConnectorType>,
133         boost::is_base_of<connector::InputConnector, typename Target::ConnectorType> >,
134     boost::tuple<typename Source::ConnectorType &, typename Target::ConnectorType &> >::type
135 connect(Source & source mpp_FnParamsKomma(), Target & target mpp_FnParamsKomma2());
136
137 //-////////////////////////////////////////////////////////////////////////
138 #elif BOOST_PP_ITERATION_FLAGS()==8 //-////////////////////////////////////
139 //-////////////////////////////////////////////////////////////////////////
140 // senf::ppi::module::detail::MultiConnectorMixinAccess member declaration 1..MAX_ARGS
141
142 template <class Module mpp_TplParamsKomma()>
143 static typename Module::ConnectorType &
144 newConnector(Module & module mpp_FnParamsKomma());
145
146 //-////////////////////////////////////////////////////////////////////////
147 #elif BOOST_PP_ITERATION_FLAGS()==3 //-////////////////////////////////////
148 //-////////////////////////////////////////////////////////////////////////
149 // Implementation 1..MAX_ARGS
150
151 //-/////////////////////////////////////////////////////////////////////////////////////////////////
152 // Map container
153
154 template <class Self_, class ConnectorType_, class KeyType_, class ContainerType_>
155 mpp_TplParams()
156 prefix_ ConnectorType_ &
157 senf::ppi::module::MultiConnectorMixin<Self_,ConnectorType_,KeyType_,ContainerType_>::
158 newConnector(mpp_FnParams())
159 {
160     std::auto_ptr<ConnectorType_> conn (new detail::MultiConnectorWrapper<Self_,ConnectorType_>);
161     KeyType_ key (static_cast<Self_*>(this)->connectorSetup(*conn mpp_CallParamsKomma()));
162     return * connectors_.insert(key, conn).first->second;
163 }
164
165 //-/////////////////////////////////////////////////////////////////////////////////////////////////
166 // Vector container
167
168 template <class Self_, class ConnectorType_, class ContainerType_>
169 mpp_TplParams()
170 prefix_ ConnectorType_ &
171 senf::ppi::module::MultiConnectorMixin<Self_,ConnectorType_,void,ContainerType_>::
172 newConnector(mpp_FnParams())
173 {
174     connectors_.push_back(new detail::MultiConnectorWrapper<Self_,ConnectorType_>);
175     ConnectorType_ & conn (connectors_.back());
176     try { static_cast<Self_*>(this)->connectorSetup(conn mpp_CallParamsKomma()); }
177     catch (...) { disconnected(conn); throw; }
178     return conn;
179 }
180
181 //-/////////////////////////////////////////////////////////////////////////////////////////////////
182 // User managed container
183
184 template <class Self_, class ConnectorType_>
185 mpp_TplParams()
186 prefix_ ConnectorType_ &
187 senf::ppi::module::MultiConnectorMixin<Self_,ConnectorType_,void,void>::
188 newConnector(mpp_FnParams())
189 {
190     std::auto_ptr<ConnectorType_> cp (new detail::MultiConnectorWrapper<Self_,ConnectorType_>);
191     ConnectorType_ & cref (*cp);
192     static_cast<Self_*>(this)->connectorSetup(cp mpp_CallParamsKomma());
193     return cref;
194 }
195
196 //-/////////////////////////////////////////////////////////////////////////////////////////////////
197 // senf::ppi::connect
198
199 template <class Source, class Target mpp_TplParamsKomma()>
200 typename boost::enable_if<
201     boost::mpl::and_<
202         senf::ppi::module::detail::IsMulticonnectorSource<Source>,
203         boost::mpl::not_< senf::ppi::module::detail::IsMulticonnectorTarget<Target> > >,
204     typename Source::ConnectorType & >::type
205 senf::ppi::connect(Source & source mpp_FnParamsKomma(), Target & target)
206 {
207     typename Source::ConnectorType & c (
208         module::detail::MultiConnectorMixinAccess::newConnector(source mpp_CallParamsKomma()));
209     connect(c, target);
210     return c;
211 }
212
213 template <class Source, class Target mpp_TplParamsKomma()>
214 typename boost::enable_if<
215     boost::mpl::and_<
216         boost::mpl::not_< senf::ppi::module::detail::IsMulticonnectorSource<Source> >,
217         senf::ppi::module::detail::IsMulticonnectorTarget<Target> >,
218     typename Target::ConnectorType & >::type
219 senf::ppi::connect(Source & source, Target & target mpp_FnParamsKomma())
220 {
221     typename Target::ConnectorType & c (
222         module::detail::MultiConnectorMixinAccess::newConnector(target mpp_CallParamsKomma()));
223     connect(source, c);
224     return c;
225 }
226
227 //-/////////////////////////////////////////////////////////////////////////////////////////////////
228 // senf::ppi::module::detail::MultiConnectorMixinAccess members
229
230 template <class Module mpp_TplParamsKomma()>
231 typename Module::ConnectorType &
232 senf::ppi::module::detail::MultiConnectorMixinAccess::newConnector(
233     Module & module mpp_FnParamsKomma())
234 {
235     return module.newConnector(mpp_CallParams());
236 }
237
238 #define BOOST_PP_ITERATION_PARAMS_2 (4, (\
239         0, \
240         SENF_MULTI_CONNECTOR_MAX_ARGS, \
241         SENF_ABSOLUTE_INCLUDE_PATH(PPI/MultiConnectorMixin.mpp), \
242         5 ))
243 #include BOOST_PP_ITERATE()
244
245 //-/////////////////////////////////////////////////////////////////////////////////////////////////
246 #elif BOOST_PP_ITERATION_FLAGS()==5 //-////////////////////////////////////
247 //-////////////////////////////////////////////////////////////////////////
248 // Implementation 1..MAX_ARGS x 1..MAX_ARGS
249
250 template <class Source, class Target mpp_TplParamsKomma() mpp_TplParamsKomma2()>
251 typename boost::enable_if<
252     boost::mpl::and_<
253         boost::is_base_of<senf::ppi::connector::OutputConnector, typename Source::ConnectorType>,
254         boost::is_base_of<senf::ppi::connector::InputConnector, typename Target::ConnectorType> >,
255     boost::tuple<typename Source::ConnectorType &, typename Target::ConnectorType &> >::type
256 senf::ppi::connect(Source & source mpp_FnParamsKomma(), Target & target mpp_FnParamsKomma2())
257 {
258     typename Source::ConnectorType & s (
259         module::detail::MultiConnectorMixinAccess::newConnector(source mpp_CallParamsKomma()));
260     typename Target::ConnectorType & t (
261         module::detail::MultiConnectorMixinAccess::newConnector(target mpp_CallParamsKomma2()));
262     connect(s,t);
263     return boost::tie(s,t);
264 }
265
266 //-////////////////////////////////////////////////////////////////////////
267 #endif //-/////////////////////////////////////////////////////////////////
268 //-////////////////////////////////////////////////////////////////////////
269 // Undefine local Macros
270
271 #undef mpp_CallParamsKomma2
272 #undef mpp_CallParams2
273 #undef mpp_FnParamsKomma2
274 #undef mpp_FnParams2
275 #undef mpp_TplParamsKomma2
276 #undef mpp_CallParamsKomma
277 #undef mpp_CallParams
278 #undef mpp_FnParamsKomma
279 #undef mpp_FnParams
280 #undef mpp_TplParamsKomma
281 #undef mpp_TplParams_
282 #undef mpp_TplParams
283
284 //-////////////////////////////////////////////////////////////////////////
285 /*
286  (save-excursion (re-search-backward "^// Undefine local Macros")
287  (forward-line 1) (delete-region (point) (progn (search-forward
288  "//-////") (forward-line -1) (point))) (insert "\n") (let ((b (point))
289  (e (progn (insert (save-excursion (re-search-backward
290  "^// Local Macros") (search-forward "#define") (beginning-of-line)
291  (buffer-substring (point) (progn (search-forward "//-////")
292  (search-backward "#define") (forward-line 1) (point))))) (point))))
293  (reverse-region b e) (shell-command-on-region b e "grep -F '#define'" nil
294  t) (goto-char b) (while (looking-at "#define") (delete-char 7) (insert
295  "#undef") (skip-chars-forward " ") (re-search-forward "[^a-zA-Z0-9_]")
296  (delete-region (1- (point)) (progn (end-of-line) (point))) (forward-line
297  1))))
298 */
299 //-////////////////////////////////////////////////////////////////////////
300 #endif //-/////////////////////////////////////////////////////////////////
301 //-///////////////////////////mpp.e////////////////////////////////////////
302
303 \f
304 // Local Variables:
305 // mode: c++
306 // fill-column: 100
307 // comment-column: 40
308 // c-file-style: "senf"
309 // indent-tabs-mode: nil
310 // ispell-local-dictionary: "american"
311 // compile-command: "scons -u test"
312 // End: