4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at
9 // http://senf.berlios.de/license.html
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on,
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
15 // Software distributed under the License is distributed on an "AS IS" basis,
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
17 // for the specific language governing rights and limitations under the License.
19 // The Original Code is Fraunhofer FOKUS code.
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V.
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
25 // Stefan Bund <g0dil@berlios.de>
29 \brief ParsedCommand Boost.Preprocesser external iteration include */
31 #if !BOOST_PP_IS_ITERATING && !defined(MPP_ParsedCommand_)
32 #define MPP_ParsedCommand_ 1
35 #include <boost/preprocessor/iteration/iterate.hpp>
36 #include <boost/preprocessor/repetition/enum_trailing.hpp>
37 #include <boost/preprocessor/repetition/enum_params.hpp>
38 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
39 #include <boost/preprocessor/cat.hpp>
40 #include <boost/preprocessor/arithmetic/inc.hpp>
41 #include <boost/preprocessor/arithmetic/sub.hpp>
42 #include <boost/preprocessor/repetition/repeat.hpp>
43 #include <boost/type_traits/remove_reference.hpp>
44 #include <boost/type_traits/remove_const.hpp>
45 #include <boost/bind.hpp>
46 #include <boost/mpl/vector.hpp>
47 #include <boost/mpl/at.hpp>
48 #include "senf/Utils/IgnoreValue.hh"
50 //-///////////////////////////mpp.p////////////////////////////////////////
51 #elif BOOST_PP_IS_ITERATING //-////////////////////////////////////////////
52 //-////////////////////////////////////////////////////////////////////////
55 #define mpp_ArgTypeN(n) BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(n)), _type)
56 #define mpp_ArgN(n) BOOST_PP_CAT(arg, BOOST_PP_INC(n))
58 #define mpp_TrailingArgTypes_(z,n,d) typename traits::mpp_ArgTypeN(n)
59 #define mpp_TrailingArgTypes() BOOST_PP_ENUM_TRAILING( BOOST_PP_ITERATION(), mpp_TrailingArgTypes_, _ )
61 #define mpp_ArgTypes_(z,n,d) mpp_ArgTypeN(n)
62 #define mpp_ArgTypes() BOOST_PP_ENUM( BOOST_PP_ITERATION(), mpp_ArgTypes_, _ )
64 #define mpp_Args_(z,n,d) mpp_ArgN(n)
65 #define mpp_TrailingArgs() BOOST_PP_ENUM_TRAILING( BOOST_PP_ITERATION(), mpp_Args_, _ )
67 #define mpp_BindArgs_(z,n,d) BOOST_PP_CAT( _, BOOST_PP_INC(BOOST_PP_INC(n)))
68 #define mpp_TrailingBindArgs() BOOST_PP_ENUM_TRAILING( BOOST_PP_ITERATION(), mpp_BindArgs_, _ )
70 //-////////////////////////////////////////////////////////////////////////
71 #if BOOST_PP_ITERATION_FLAGS()==1 //-//////////////////////////////////////
72 //-////////////////////////////////////////////////////////////////////////
76 template <class FunctionTraits, class ReturnValue>
77 class ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION() >
78 : public ParsedCommandOverloadBase
81 typedef boost::intrusive_ptr<ParsedCommandOverload> ptr;
82 typedef FunctionTraits traits;
83 typedef boost::function<typename traits::result_type(std::ostream &
84 mpp_TrailingArgTypes())> Function;
85 typedef typename senf::remove_cvref<typename traits::result_type>::type result_type;
86 typedef boost::function<void (result_type const &, std::ostream &)> Formatter;
88 # define mpp_l(z,n,d) \
89 typedef typename senf::remove_cvref< typename traits::mpp_ArgTypeN(n) >::type \
91 BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l, _ )
94 typedef boost::mpl::vector< mpp_ArgTypes() > arg_types;
96 static ptr create(Function fn);
98 void formatter(Formatter f);
100 using ParsedCommandOverloadBase::arg;
101 template <unsigned n>
102 detail::ArgumentInfo<typename boost::mpl::at_c<arg_types, n>::type> & arg() const;
104 void function(Function fn);
109 ParsedCommandOverload(Function fn);
111 virtual void v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
115 Formatter formatter_;
118 template <class FunctionTraits>
119 class ParsedCommandOverload<FunctionTraits, void, BOOST_PP_ITERATION() >
120 : public ParsedCommandOverloadBase
123 typedef boost::intrusive_ptr<ParsedCommandOverload> ptr;
124 typedef FunctionTraits traits;
125 typedef boost::function<typename traits::result_type(std::ostream &
126 mpp_TrailingArgTypes())> Function;
127 typedef void result_type;
129 # define mpp_l(z,n,d) \
130 typedef typename senf::remove_cvref< typename traits::mpp_ArgTypeN(n) >::type \
132 BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l, _ )
135 typedef boost::mpl::vector< mpp_ArgTypes() > arg_types;
137 static ptr create(Function fn);
139 using ParsedCommandOverloadBase::arg;
140 template <unsigned n>
141 detail::ArgumentInfo<typename boost::mpl::at_c<arg_types, n>::type> & arg() const;
143 void function(Function fn);
148 ParsedCommandOverload(Function fn);
150 virtual void v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
156 //-////////////////////////////////////////////////////////////////////////
157 #elif BOOST_PP_ITERATION_FLAGS()==2 //-////////////////////////////////////
158 //-////////////////////////////////////////////////////////////////////////
160 // inline template implementation (.cti)
162 template <class FunctionTraits, class ReturnValue>
163 prefix_ typename senf::console::ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION() >::ptr
164 senf::console::ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION() >::
167 return ptr(new ParsedCommandOverload(fn));
170 template <class FunctionTraits, class ReturnValue>
172 senf::console::ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION() >::
173 formatter(Formatter f)
178 template <class FunctionTraits, class ReturnValue>
179 template <unsigned n>
180 senf::console::detail::ArgumentInfo<
181 typename boost::mpl::at_c<
182 typename senf::console::ParsedCommandOverload<
183 FunctionTraits, ReturnValue, BOOST_PP_ITERATION()>::arg_types,
185 senf::console::ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION() >::
188 return static_cast< detail::ArgumentInfo<
189 typename boost::mpl::at_c<arg_types, n>::type > & >(arg(n));
192 template <class FunctionTraits, class ReturnValue>
194 senf::console::ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION() >::
195 function(Function fn)
200 template <class FunctionTraits, class ReturnValue>
202 senf::console::ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION()>::
203 ParsedCommandOverload(Function fn)
206 # define mpp_l(z,n,d) addParameter< mpp_ArgTypeN(n) >();
207 BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l, _ )
211 template <class FunctionTraits>
212 prefix_ typename senf::console::ParsedCommandOverload<FunctionTraits, void, BOOST_PP_ITERATION() >::ptr
213 senf::console::ParsedCommandOverload<FunctionTraits, void, BOOST_PP_ITERATION() >::
216 return ptr(new ParsedCommandOverload(fn));
219 template <class FunctionTraits>
220 template <unsigned n>
221 senf::console::detail::ArgumentInfo<
222 typename boost::mpl::at_c<
223 typename senf::console::ParsedCommandOverload<
224 FunctionTraits, void, BOOST_PP_ITERATION()>::arg_types,
226 senf::console::ParsedCommandOverload<FunctionTraits, void, BOOST_PP_ITERATION() >::
229 return static_cast< detail::ArgumentInfo<
230 typename boost::mpl::at_c<arg_types, n>::type > & >(arg(n));
233 template <class FunctionTraits>
235 senf::console::ParsedCommandOverload<FunctionTraits, void, BOOST_PP_ITERATION() >::
236 function(Function fn)
241 template <class FunctionTraits>
243 senf::console::ParsedCommandOverload<FunctionTraits, void, BOOST_PP_ITERATION() >::
244 ParsedCommandOverload(Function fn)
247 # define mpp_l(z,n,d) addParameter< mpp_ArgTypeN(n) >();
248 BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l, _ )
252 //-////////////////////////////////////////////////////////////////////////
253 #elif BOOST_PP_ITERATION_FLAGS()==3 //-////////////////////////////////////
254 //-////////////////////////////////////////////////////////////////////////
256 // non-inline template implementation (.ct)
258 template <class FunctionTraits, class ReturnValue>
259 prefix_ void senf::console::ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION() >::
260 v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
263 // We NEED to know the number of arguments beforehand so we can assign default values
264 // correctly ... hrmpf ...
265 unsigned nArgs ( std::distance(command.arguments().begin(), command.arguments().end()) );
266 if ( nArgs > BOOST_PP_ITERATION() )
267 throw SyntaxErrorException("invalid number of arguments");
268 int nDefaults ( BOOST_PP_ITERATION() - nArgs );
269 senf::IGNORE( nDefaults );
271 typedef typename boost::range_reverse_iterator<const ParseCommandInfo::ArgumentsRange>::type
273 riterator i (boost::rbegin(command.arguments()));
274 riterator const i_end (boost::rend(command.arguments()));
276 # define mpp_l(z,n,d) \
277 mpp_ArgTypeN(n) mpp_ArgN(n) (arg<n>().defaultValue); \
278 if (! arg(n).hasDefault || nDefaults-- <= 0) { \
280 throw SyntaxErrorException("invalid number of arguments"); \
281 if (arg<n>().parser) \
282 arg<n>().parser( *(i++), mpp_ArgN(n) ); \
284 ArgumentTraits< mpp_ArgTypeN(n) >::parse( *(i++), mpp_ArgN(n) ); \
286 # define mpp_l_(z,n,d) mpp_l(z, BOOST_PP_SUB(BOOST_PP_DEC(BOOST_PP_ITERATION()), n), d)
287 BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l_, _ )
291 ReturnValue rvv (function_(os mpp_TrailingArgs()));
296 ReturnValueTraits<result_type>::format(rvv, os);
300 template <class FunctionTraits>
301 prefix_ void senf::console::ParsedCommandOverload<FunctionTraits, void, BOOST_PP_ITERATION() >::
302 v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
305 // We NEED to know the number of arguments beforehand so we can assign default values
306 // correctly ... hrmpf ...
307 unsigned nArgs ( std::distance(command.arguments().begin(), command.arguments().end()) );
308 if ( nArgs > BOOST_PP_ITERATION() )
309 throw SyntaxErrorException("invalid number of arguments");
310 int nDefaults ( BOOST_PP_ITERATION() - nArgs );
311 senf::IGNORE( nDefaults );
313 typedef typename boost::range_reverse_iterator<const ParseCommandInfo::ArgumentsRange>::type
315 riterator i (boost::rbegin(command.arguments()));
316 riterator const i_end (boost::rend(command.arguments()));
318 # define mpp_l(z,n,d) \
319 mpp_ArgTypeN(n) mpp_ArgN(n) (arg<n>().defaultValue); \
320 if (! arg(n).hasDefault || nDefaults-- <= 0) { \
322 throw SyntaxErrorException("invalid number of arguments"); \
323 if (arg<n>().parser) \
324 arg<n>().parser( *(i++), mpp_ArgN(n) ); \
326 ArgumentTraits< mpp_ArgTypeN(n) >::parse( *(i++), mpp_ArgN(n) ); \
328 # define mpp_l_(z,n,d) mpp_l(z, BOOST_PP_SUB(BOOST_PP_DEC(BOOST_PP_ITERATION()), n), d)
329 BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l_, _ )
333 function_(os mpp_TrailingArgs());
336 //-////////////////////////////////////////////////////////////////////////
337 #elif BOOST_PP_ITERATION_FLAGS()==4 //-////////////////////////////////////
338 //-////////////////////////////////////////////////////////////////////////
340 // CreateParsedCommandOverload
342 template <class Traits>
343 struct CreateParsedCommandOverload<Traits, true, BOOST_PP_ITERATION()>
345 typedef typename Traits::traits traits;
347 template <class Function>
348 static typename senf::console::ParsedCommandOverload<traits>::ptr create(Function fn)
350 return senf::console::ParsedCommandOverload<traits>::create(
351 boost::bind(fn mpp_TrailingBindArgs()) );
356 //-////////////////////////////////////////////////////////////////////////
357 #elif BOOST_PP_ITERATION_FLAGS()==5 //-////////////////////////////////////
358 //-////////////////////////////////////////////////////////////////////////
360 // Create keyword arg forwarding functions
362 template <BOOST_PP_ENUM_PARAMS( BOOST_PP_ITERATION(), class A ) >
363 next_type arg ( BOOST_PP_ENUM_BINARY_PARAMS( BOOST_PP_ITERATION(), A, const & a ),
364 typename arg_params::match< BOOST_PP_ENUM_PARAMS( BOOST_PP_ITERATION(), A ) >::type
366 return argInfo( kw(BOOST_PP_ENUM_PARAMS( BOOST_PP_ITERATION(), a )) );
369 //-////////////////////////////////////////////////////////////////////////
370 #endif //-/////////////////////////////////////////////////////////////////
371 //-////////////////////////////////////////////////////////////////////////
372 // Undefine local Macros
374 #undef mpp_TrailingBindArgs
377 #undef mpp_TrailingArgs
383 #undef mpp_TrailingArgTypes
384 #undef mpp_TrailingArgTypes_
389 //-////////////////////////////////////////////////////////////////////////
390 #endif //-/////////////////////////////////////////////////////////////////
391 //-///////////////////////////mpp.e////////////////////////////////////////
397 // comment-column: 40
398 // c-file-style: "senf"
399 // indent-tabs-mode: nil
400 // ispell-local-dictionary: "american"
401 // compile-command: "scons -u test"