4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 // Stefan Bund <g0dil@berlios.de>
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.
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.
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.
24 \brief ParsedCommand Boost.Preprocesser external iteration include */
26 #if !BOOST_PP_IS_ITERATING && !defined(MPP_ParsedCommand_)
27 #define MPP_ParsedCommand_ 1
30 #include <boost/preprocessor/iteration/iterate.hpp>
31 #include <boost/preprocessor/repetition/enum_trailing.hpp>
32 #include <boost/preprocessor/repetition/enum_params.hpp>
33 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
34 #include <boost/preprocessor/cat.hpp>
35 #include <boost/preprocessor/arithmetic/inc.hpp>
36 #include <boost/preprocessor/arithmetic/sub.hpp>
37 #include <boost/preprocessor/repetition/repeat.hpp>
38 #include <boost/type_traits/remove_reference.hpp>
39 #include <boost/type_traits/remove_const.hpp>
40 #include <boost/bind.hpp>
41 #include <boost/mpl/vector.hpp>
42 #include <boost/mpl/at.hpp>
43 #include "senf/Utils/IgnoreValue.hh"
45 // ///////////////////////////mpp.p////////////////////////////////////////
46 #elif BOOST_PP_IS_ITERATING // ////////////////////////////////////////////
47 // ////////////////////////////////////////////////////////////////////////
50 #define mpp_ArgTypeN(n) BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(n)), _type)
51 #define mpp_ArgN(n) BOOST_PP_CAT(arg, BOOST_PP_INC(n))
53 #define mpp_TrailingArgTypes_(z,n,d) typename traits::mpp_ArgTypeN(n)
54 #define mpp_TrailingArgTypes() BOOST_PP_ENUM_TRAILING( BOOST_PP_ITERATION(), mpp_TrailingArgTypes_, _ )
56 #define mpp_ArgTypes_(z,n,d) mpp_ArgTypeN(n)
57 #define mpp_ArgTypes() BOOST_PP_ENUM( BOOST_PP_ITERATION(), mpp_ArgTypes_, _ )
59 #define mpp_Args_(z,n,d) mpp_ArgN(n)
60 #define mpp_TrailingArgs() BOOST_PP_ENUM_TRAILING( BOOST_PP_ITERATION(), mpp_Args_, _ )
62 #define mpp_BindArgs_(z,n,d) BOOST_PP_CAT( _, BOOST_PP_INC(BOOST_PP_INC(n)))
63 #define mpp_TrailingBindArgs() BOOST_PP_ENUM_TRAILING( BOOST_PP_ITERATION(), mpp_BindArgs_, _ )
65 // ////////////////////////////////////////////////////////////////////////
66 #if BOOST_PP_ITERATION_FLAGS()==1 // //////////////////////////////////////
67 // ////////////////////////////////////////////////////////////////////////
71 template <class FunctionTraits, class ReturnValue>
72 class ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION() >
73 : public ParsedCommandOverloadBase
76 typedef boost::intrusive_ptr<ParsedCommandOverload> ptr;
77 typedef FunctionTraits traits;
78 typedef boost::function<typename traits::result_type(std::ostream &
79 mpp_TrailingArgTypes())> Function;
80 typedef typename senf::remove_cvref<typename traits::result_type>::type result_type;
81 typedef boost::function<void (result_type const &, std::ostream &)> Formatter;
83 # define mpp_l(z,n,d) \
84 typedef typename senf::remove_cvref< typename traits::mpp_ArgTypeN(n) >::type \
86 BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l, _ )
89 typedef boost::mpl::vector< mpp_ArgTypes() > arg_types;
91 static ptr create(Function fn);
93 void formatter(Formatter f);
95 using ParsedCommandOverloadBase::arg;
97 detail::ArgumentInfo<typename boost::mpl::at_c<arg_types, n>::type> & arg() const;
99 void function(Function fn);
104 ParsedCommandOverload(Function fn);
106 virtual void v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
110 Formatter formatter_;
113 template <class FunctionTraits>
114 class ParsedCommandOverload<FunctionTraits, void, BOOST_PP_ITERATION() >
115 : public ParsedCommandOverloadBase
118 typedef boost::intrusive_ptr<ParsedCommandOverload> ptr;
119 typedef FunctionTraits traits;
120 typedef boost::function<typename traits::result_type(std::ostream &
121 mpp_TrailingArgTypes())> Function;
122 typedef void result_type;
124 # define mpp_l(z,n,d) \
125 typedef typename senf::remove_cvref< typename traits::mpp_ArgTypeN(n) >::type \
127 BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l, _ )
130 typedef boost::mpl::vector< mpp_ArgTypes() > arg_types;
132 static ptr create(Function fn);
134 using ParsedCommandOverloadBase::arg;
135 template <unsigned n>
136 detail::ArgumentInfo<typename boost::mpl::at_c<arg_types, n>::type> & arg() const;
138 void function(Function fn);
143 ParsedCommandOverload(Function fn);
145 virtual void v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
151 // ////////////////////////////////////////////////////////////////////////
152 #elif BOOST_PP_ITERATION_FLAGS()==2 // ////////////////////////////////////
153 // ////////////////////////////////////////////////////////////////////////
155 // inline template implementation (.cti)
157 template <class FunctionTraits, class ReturnValue>
158 prefix_ typename senf::console::ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION() >::ptr
159 senf::console::ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION() >::
162 return ptr(new ParsedCommandOverload(fn));
165 template <class FunctionTraits, class ReturnValue>
167 senf::console::ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION() >::
168 formatter(Formatter f)
173 template <class FunctionTraits, class ReturnValue>
174 template <unsigned n>
175 senf::console::detail::ArgumentInfo<
176 typename boost::mpl::at_c<
177 typename senf::console::ParsedCommandOverload<
178 FunctionTraits, ReturnValue, BOOST_PP_ITERATION()>::arg_types,
180 senf::console::ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION() >::
183 return static_cast< detail::ArgumentInfo<
184 typename boost::mpl::at_c<arg_types, n>::type > & >(arg(n));
187 template <class FunctionTraits, class ReturnValue>
189 senf::console::ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION() >::
190 function(Function fn)
195 template <class FunctionTraits, class ReturnValue>
197 senf::console::ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION()>::
198 ParsedCommandOverload(Function fn)
201 # define mpp_l(z,n,d) addParameter< mpp_ArgTypeN(n) >();
202 BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l, _ )
206 template <class FunctionTraits>
207 prefix_ typename senf::console::ParsedCommandOverload<FunctionTraits, void, BOOST_PP_ITERATION() >::ptr
208 senf::console::ParsedCommandOverload<FunctionTraits, void, BOOST_PP_ITERATION() >::
211 return ptr(new ParsedCommandOverload(fn));
214 template <class FunctionTraits>
215 template <unsigned n>
216 senf::console::detail::ArgumentInfo<
217 typename boost::mpl::at_c<
218 typename senf::console::ParsedCommandOverload<
219 FunctionTraits, void, BOOST_PP_ITERATION()>::arg_types,
221 senf::console::ParsedCommandOverload<FunctionTraits, void, BOOST_PP_ITERATION() >::
224 return static_cast< detail::ArgumentInfo<
225 typename boost::mpl::at_c<arg_types, n>::type > & >(arg(n));
228 template <class FunctionTraits>
230 senf::console::ParsedCommandOverload<FunctionTraits, void, BOOST_PP_ITERATION() >::
231 function(Function fn)
236 template <class FunctionTraits>
238 senf::console::ParsedCommandOverload<FunctionTraits, void, BOOST_PP_ITERATION() >::
239 ParsedCommandOverload(Function fn)
242 # define mpp_l(z,n,d) addParameter< mpp_ArgTypeN(n) >();
243 BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l, _ )
247 // ////////////////////////////////////////////////////////////////////////
248 #elif BOOST_PP_ITERATION_FLAGS()==3 // ////////////////////////////////////
249 // ////////////////////////////////////////////////////////////////////////
251 // non-inline template implementation (.ct)
253 template <class FunctionTraits, class ReturnValue>
254 prefix_ void senf::console::ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION() >::
255 v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
258 // We NEED to know the number of arguments beforehand so we can assign default values
259 // correctly ... hrmpf ...
260 unsigned nArgs ( std::distance(command.arguments().begin(), command.arguments().end()) );
261 if ( nArgs > BOOST_PP_ITERATION() )
262 throw SyntaxErrorException("invalid number of arguments");
263 int nDefaults ( BOOST_PP_ITERATION() - nArgs );
264 senf::IGNORE( nDefaults );
266 typedef typename boost::range_reverse_iterator<const ParseCommandInfo::ArgumentsRange>::type
268 riterator i (boost::rbegin(command.arguments()));
269 riterator const i_end (boost::rend(command.arguments()));
271 # define mpp_l(z,n,d) \
272 mpp_ArgTypeN(n) mpp_ArgN(n) (arg<n>().defaultValue); \
273 if (! arg(n).hasDefault || nDefaults-- <= 0) { \
275 throw SyntaxErrorException("invalid number of arguments"); \
276 if (arg<n>().parser) \
277 arg<n>().parser( *(i++), mpp_ArgN(n) ); \
279 ArgumentTraits< mpp_ArgTypeN(n) >::parse( *(i++), mpp_ArgN(n) ); \
281 # define mpp_l_(z,n,d) mpp_l(z, BOOST_PP_SUB(BOOST_PP_DEC(BOOST_PP_ITERATION()), n), d)
282 BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l_, _ )
286 ReturnValue rvv (function_(os mpp_TrailingArgs()));
291 ReturnValueTraits<result_type>::format(rvv, os);
295 template <class FunctionTraits>
296 prefix_ void senf::console::ParsedCommandOverload<FunctionTraits, void, BOOST_PP_ITERATION() >::
297 v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
300 // We NEED to know the number of arguments beforehand so we can assign default values
301 // correctly ... hrmpf ...
302 unsigned nArgs ( std::distance(command.arguments().begin(), command.arguments().end()) );
303 if ( nArgs > BOOST_PP_ITERATION() )
304 throw SyntaxErrorException("invalid number of arguments");
305 int nDefaults ( BOOST_PP_ITERATION() - nArgs );
306 senf::IGNORE( nDefaults );
308 typedef typename boost::range_reverse_iterator<const ParseCommandInfo::ArgumentsRange>::type
310 riterator i (boost::rbegin(command.arguments()));
311 riterator const i_end (boost::rend(command.arguments()));
313 # define mpp_l(z,n,d) \
314 mpp_ArgTypeN(n) mpp_ArgN(n) (arg<n>().defaultValue); \
315 if (! arg(n).hasDefault || nDefaults-- <= 0) { \
317 throw SyntaxErrorException("invalid number of arguments"); \
318 if (arg<n>().parser) \
319 arg<n>().parser( *(i++), mpp_ArgN(n) ); \
321 ArgumentTraits< mpp_ArgTypeN(n) >::parse( *(i++), mpp_ArgN(n) ); \
323 # define mpp_l_(z,n,d) mpp_l(z, BOOST_PP_SUB(BOOST_PP_DEC(BOOST_PP_ITERATION()), n), d)
324 BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l_, _ )
328 function_(os mpp_TrailingArgs());
331 // ////////////////////////////////////////////////////////////////////////
332 #elif BOOST_PP_ITERATION_FLAGS()==4 // ////////////////////////////////////
333 // ////////////////////////////////////////////////////////////////////////
335 // CreateParsedCommandOverload
337 template <class Traits>
338 struct CreateParsedCommandOverload<Traits, true, BOOST_PP_ITERATION()>
340 typedef typename Traits::traits traits;
342 template <class Function>
343 static typename senf::console::ParsedCommandOverload<traits>::ptr create(Function fn)
345 return senf::console::ParsedCommandOverload<traits>::create(
346 boost::bind(fn mpp_TrailingBindArgs()) );
351 // ////////////////////////////////////////////////////////////////////////
352 #elif BOOST_PP_ITERATION_FLAGS()==5 // ////////////////////////////////////
353 // ////////////////////////////////////////////////////////////////////////
355 // Create keyword arg forwarding functions
357 template <BOOST_PP_ENUM_PARAMS( BOOST_PP_ITERATION(), class A ) >
358 next_type arg ( BOOST_PP_ENUM_BINARY_PARAMS( BOOST_PP_ITERATION(), A, const & a ),
359 typename arg_params::match< BOOST_PP_ENUM_PARAMS( BOOST_PP_ITERATION(), A ) >::type
361 return argInfo( kw(BOOST_PP_ENUM_PARAMS( BOOST_PP_ITERATION(), a )) );
364 // ////////////////////////////////////////////////////////////////////////
365 #endif // /////////////////////////////////////////////////////////////////
366 // ////////////////////////////////////////////////////////////////////////
367 // Undefine local Macros
369 #undef mpp_TrailingBindArgs
372 #undef mpp_TrailingArgs
378 #undef mpp_TrailingArgTypes
379 #undef mpp_TrailingArgTypes_
384 // ////////////////////////////////////////////////////////////////////////
385 #endif // /////////////////////////////////////////////////////////////////
386 // ///////////////////////////mpp.e////////////////////////////////////////
392 // comment-column: 40
393 // c-file-style: "senf"
394 // indent-tabs-mode: nil
395 // ispell-local-dictionary: "american"
396 // compile-command: "scons -u test"