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>
44 // ///////////////////////////mpp.p////////////////////////////////////////
45 #elif BOOST_PP_IS_ITERATING // ////////////////////////////////////////////
46 // ////////////////////////////////////////////////////////////////////////
49 #define mpp_ArgTypeN(n) BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(n)), _type)
50 #define mpp_ArgN(n) BOOST_PP_CAT(arg, BOOST_PP_INC(n))
52 #define mpp_TrailingArgTypes_(z,n,d) typename traits::mpp_ArgTypeN(n)
53 #define mpp_TrailingArgTypes() BOOST_PP_ENUM_TRAILING( BOOST_PP_ITERATION(), mpp_TrailingArgTypes_, _ )
55 #define mpp_ArgTypes_(z,n,d) mpp_ArgTypeN(n)
56 #define mpp_ArgTypes() BOOST_PP_ENUM( BOOST_PP_ITERATION(), mpp_ArgTypes_, _ )
58 #define mpp_Args_(z,n,d) mpp_ArgN(n)
59 #define mpp_TrailingArgs() BOOST_PP_ENUM_TRAILING( BOOST_PP_ITERATION(), mpp_Args_, _ )
61 #define mpp_BindArgs_(z,n,d) BOOST_PP_CAT( _, BOOST_PP_INC(BOOST_PP_INC(n)))
62 #define mpp_TrailingBindArgs() BOOST_PP_ENUM_TRAILING( BOOST_PP_ITERATION(), mpp_BindArgs_, _ )
64 // ////////////////////////////////////////////////////////////////////////
65 #if BOOST_PP_ITERATION_FLAGS()==1 // //////////////////////////////////////
66 // ////////////////////////////////////////////////////////////////////////
70 template <class FunctionTraits, class ReturnValue>
71 class ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION() >
72 : public ParsedCommandOverloadBase
75 typedef boost::intrusive_ptr<ParsedCommandOverload> ptr;
76 typedef FunctionTraits traits;
77 typedef boost::function<typename traits::result_type(std::ostream &
78 mpp_TrailingArgTypes())> Function;
79 typedef typename senf::remove_cvref<typename traits::result_type>::type result_type;
80 typedef boost::function<void (result_type const &, std::ostream &)> Formatter;
82 # define mpp_l(z,n,d) \
83 typedef typename senf::remove_cvref< typename traits::mpp_ArgTypeN(n) >::type \
85 BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l, _ )
88 typedef boost::mpl::vector< mpp_ArgTypes() > arg_types;
90 static ptr create(Function fn);
92 void formatter(Formatter f);
94 using ParsedCommandOverloadBase::arg;
96 detail::ArgumentInfo<typename boost::mpl::at_c<arg_types, n>::type> & arg() const;
98 void function(Function fn);
103 ParsedCommandOverload(Function fn);
105 virtual void v_execute(std::ostream & os, ParseCommandInfo const & command) const;
108 Formatter formatter_;
111 template <class FunctionTraits>
112 class ParsedCommandOverload<FunctionTraits, void, BOOST_PP_ITERATION() >
113 : public ParsedCommandOverloadBase
116 typedef boost::intrusive_ptr<ParsedCommandOverload> ptr;
117 typedef FunctionTraits traits;
118 typedef boost::function<typename traits::result_type(std::ostream &
119 mpp_TrailingArgTypes())> Function;
120 typedef void result_type;
122 # define mpp_l(z,n,d) \
123 typedef typename senf::remove_cvref< typename traits::mpp_ArgTypeN(n) >::type \
125 BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l, _ )
128 typedef boost::mpl::vector< mpp_ArgTypes() > arg_types;
130 static ptr create(Function fn);
132 using ParsedCommandOverloadBase::arg;
133 template <unsigned n>
134 detail::ArgumentInfo<typename boost::mpl::at_c<arg_types, n>::type> & arg() const;
136 void function(Function fn);
141 ParsedCommandOverload(Function fn);
143 virtual void v_execute(std::ostream & os, ParseCommandInfo const & command) const;
148 // ////////////////////////////////////////////////////////////////////////
149 #elif BOOST_PP_ITERATION_FLAGS()==2 // ////////////////////////////////////
150 // ////////////////////////////////////////////////////////////////////////
152 // inline template implementation (.cti)
154 template <class FunctionTraits, class ReturnValue>
155 prefix_ typename senf::console::ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION() >::ptr
156 senf::console::ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION() >::
159 return ptr(new ParsedCommandOverload(fn));
162 template <class FunctionTraits, class ReturnValue>
164 senf::console::ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION() >::
165 formatter(Formatter f)
170 template <class FunctionTraits, class ReturnValue>
171 template <unsigned n>
172 senf::console::detail::ArgumentInfo<
173 typename boost::mpl::at_c<
174 typename senf::console::ParsedCommandOverload<
175 FunctionTraits, ReturnValue, BOOST_PP_ITERATION()>::arg_types,
177 senf::console::ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION() >::
180 return static_cast< detail::ArgumentInfo<
181 typename boost::mpl::at_c<arg_types, n>::type > & >(arg(n));
184 template <class FunctionTraits, class ReturnValue>
186 senf::console::ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION() >::
187 function(Function fn)
192 template <class FunctionTraits, class ReturnValue>
194 senf::console::ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION()>::
195 ParsedCommandOverload(Function fn)
198 # define mpp_l(z,n,d) addParameter< mpp_ArgTypeN(n) >();
199 BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l, _ )
203 template <class FunctionTraits>
204 prefix_ typename senf::console::ParsedCommandOverload<FunctionTraits, void, BOOST_PP_ITERATION() >::ptr
205 senf::console::ParsedCommandOverload<FunctionTraits, void, BOOST_PP_ITERATION() >::
208 return ptr(new ParsedCommandOverload(fn));
211 template <class FunctionTraits>
212 template <unsigned n>
213 senf::console::detail::ArgumentInfo<
214 typename boost::mpl::at_c<
215 typename senf::console::ParsedCommandOverload<
216 FunctionTraits, void, BOOST_PP_ITERATION()>::arg_types,
218 senf::console::ParsedCommandOverload<FunctionTraits, void, BOOST_PP_ITERATION() >::
221 return static_cast< detail::ArgumentInfo<
222 typename boost::mpl::at_c<arg_types, n>::type > & >(arg(n));
225 template <class FunctionTraits>
227 senf::console::ParsedCommandOverload<FunctionTraits, void, BOOST_PP_ITERATION() >::
228 function(Function fn)
233 template <class FunctionTraits>
235 senf::console::ParsedCommandOverload<FunctionTraits, void, BOOST_PP_ITERATION() >::
236 ParsedCommandOverload(Function fn)
239 # define mpp_l(z,n,d) addParameter< mpp_ArgTypeN(n) >();
240 BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l, _ )
244 // ////////////////////////////////////////////////////////////////////////
245 #elif BOOST_PP_ITERATION_FLAGS()==3 // ////////////////////////////////////
246 // ////////////////////////////////////////////////////////////////////////
248 // non-inline template implementation (.ct)
250 template <class FunctionTraits, class ReturnValue>
251 prefix_ void senf::console::ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION() >::
252 v_execute(std::ostream & os, ParseCommandInfo const & command)
255 // We NEED to know the number of arguments beforehand so we can assign default values
256 // correctly ... hrmpf ...
257 unsigned nArgs ( std::distance(command.arguments().begin(), command.arguments().end()) );
258 if ( nArgs > BOOST_PP_ITERATION() )
259 throw SyntaxErrorException("invalid number of arguments");
260 int nDefaults ( BOOST_PP_ITERATION() - nArgs );
263 typedef typename boost::range_reverse_iterator<const ParseCommandInfo::ArgumentsRange>::type
265 riterator i (boost::rbegin(command.arguments()));
266 riterator const i_end (boost::rend(command.arguments()));
268 # define mpp_l(z,n,d) \
269 mpp_ArgTypeN(n) mpp_ArgN(n) (arg<n>().defaultValue); \
270 if (! arg(n).hasDefault || nDefaults-- <= 0) { \
272 throw SyntaxErrorException("invalid number of arguments"); \
273 if (arg<n>().parser) \
274 arg<n>().parser( *(i++), mpp_ArgN(n) ); \
276 ArgumentTraits< mpp_ArgTypeN(n) >::parse( *(i++), mpp_ArgN(n) ); \
278 # define mpp_l_(z,n,d) mpp_l(z, BOOST_PP_SUB(BOOST_PP_DEC(BOOST_PP_ITERATION()), n), d)
279 BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l_, _ )
284 formatter_( function_(os mpp_TrailingArgs()), os );
286 ReturnValueTraits<result_type>::format( function_(os mpp_TrailingArgs()), os );
290 template <class FunctionTraits>
291 prefix_ void senf::console::ParsedCommandOverload<FunctionTraits, void, BOOST_PP_ITERATION() >::
292 v_execute(std::ostream & os, ParseCommandInfo const & command)
295 // We NEED to know the number of arguments beforehand so we can assign default values
296 // correctly ... hrmpf ...
297 unsigned nArgs ( std::distance(command.arguments().begin(), command.arguments().end()) );
298 if ( nArgs > BOOST_PP_ITERATION() )
299 throw SyntaxErrorException("invalid number of arguments");
300 int nDefaults ( BOOST_PP_ITERATION() - nArgs );
303 typedef typename boost::range_reverse_iterator<const ParseCommandInfo::ArgumentsRange>::type
305 riterator i (boost::rbegin(command.arguments()));
306 riterator const i_end (boost::rend(command.arguments()));
308 # define mpp_l(z,n,d) \
309 mpp_ArgTypeN(n) mpp_ArgN(n) (arg<n>().defaultValue); \
310 if (! arg(n).hasDefault || nDefaults-- <= 0) { \
312 throw SyntaxErrorException("invalid number of arguments"); \
313 if (arg<n>().parser) \
314 arg<n>().parser( *(i++), mpp_ArgN(n) ); \
316 ArgumentTraits< mpp_ArgTypeN(n) >::parse( *(i++), mpp_ArgN(n) ); \
318 # define mpp_l_(z,n,d) mpp_l(z, BOOST_PP_SUB(BOOST_PP_DEC(BOOST_PP_ITERATION()), n), d)
319 BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l_, _ )
323 function_(os mpp_TrailingArgs());
326 // ////////////////////////////////////////////////////////////////////////
327 #elif BOOST_PP_ITERATION_FLAGS()==4 // ////////////////////////////////////
328 // ////////////////////////////////////////////////////////////////////////
330 // CreateParsedCommandOverload
332 template <class Traits>
333 struct CreateParsedCommandOverload<Traits, true, BOOST_PP_ITERATION()>
335 typedef typename Traits::traits traits;
337 template <class Function>
338 static typename senf::console::ParsedCommandOverload<traits>::ptr create(Function fn)
340 return senf::console::ParsedCommandOverload<traits>::create(
341 boost::bind(fn mpp_TrailingBindArgs()) );
346 // ////////////////////////////////////////////////////////////////////////
347 #elif BOOST_PP_ITERATION_FLAGS()==5 // ////////////////////////////////////
348 // ////////////////////////////////////////////////////////////////////////
350 // Create keyword arg forwarding functions
352 template <BOOST_PP_ENUM_PARAMS( BOOST_PP_ITERATION(), class A ) >
353 next_type arg ( BOOST_PP_ENUM_BINARY_PARAMS( BOOST_PP_ITERATION(), A, const & a ),
354 typename arg_params::match< BOOST_PP_ENUM_PARAMS( BOOST_PP_ITERATION(), A ) >::type
355 kw = arg_params()) const {
356 return argInfo( kw(BOOST_PP_ENUM_PARAMS( BOOST_PP_ITERATION(), a )) );
359 // ////////////////////////////////////////////////////////////////////////
360 #endif // /////////////////////////////////////////////////////////////////
361 // ////////////////////////////////////////////////////////////////////////
362 // Undefine local Macros
364 #undef mpp_TrailingBindArgs
367 #undef mpp_TrailingArgs
373 #undef mpp_TrailingArgTypes
374 #undef mpp_TrailingArgTypes_
379 // ////////////////////////////////////////////////////////////////////////
380 #endif // /////////////////////////////////////////////////////////////////
381 // ///////////////////////////mpp.e////////////////////////////////////////
387 // comment-column: 40
388 // c-file-style: "senf"
389 // indent-tabs-mode: nil
390 // ispell-local-dictionary: "american"
391 // compile-command: "scons -u test"