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>
42 // ///////////////////////////mpp.p////////////////////////////////////////
43 #elif BOOST_PP_IS_ITERATING // ////////////////////////////////////////////
44 // ////////////////////////////////////////////////////////////////////////
47 #define mpp_ArgTypeN(n) BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(n)), _type)
48 #define mpp_ArgN(n) BOOST_PP_CAT(arg, BOOST_PP_INC(n))
50 #define mpp_ArgTypes_(z,n,d) typename traits::mpp_ArgTypeN(n)
51 #define mpp_TrailingArgTypes() BOOST_PP_ENUM_TRAILING( BOOST_PP_ITERATION(), mpp_ArgTypes_, _ )
53 #define mpp_Args_(z,n,d) mpp_ArgN(n)
54 #define mpp_TrailingArgs() BOOST_PP_ENUM_TRAILING( BOOST_PP_ITERATION(), mpp_Args_, _ )
56 #define mpp_BindArgs_(z,n,d) BOOST_PP_CAT( _, BOOST_PP_INC(BOOST_PP_INC(n)))
57 #define mpp_TrailingBindArgs() BOOST_PP_ENUM_TRAILING( BOOST_PP_ITERATION(), mpp_BindArgs_, _ )
59 // ////////////////////////////////////////////////////////////////////////
60 #if BOOST_PP_ITERATION_FLAGS()==1 // //////////////////////////////////////
61 // ////////////////////////////////////////////////////////////////////////
65 template <class FunctionTraits, class ReturnValue>
66 class ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION() >
67 : public ParsedCommandOverloadBase
70 typedef boost::intrusive_ptr<ParsedCommandOverload> ptr;
71 typedef FunctionTraits traits;
72 typedef boost::function<typename traits::result_type(std::ostream &
73 mpp_TrailingArgTypes())> Function;
74 typedef typename senf::remove_cvref<typename traits::result_type>::type result_type;
75 typedef boost::function<void (result_type const &, std::ostream &)> Formatter;
77 # define mpp_l(z,n,d) \
78 typedef typename senf::remove_cvref< typename traits::mpp_ArgTypeN(n) >::type \
80 BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l, _ )
83 static ptr create(Function fn);
85 void formatter(Formatter f);
90 ParsedCommandOverload(Function fn);
92 virtual void v_execute(std::ostream & os, ParseCommandInfo const & command) const;
98 template <class FunctionTraits>
99 class ParsedCommandOverload<FunctionTraits, void, BOOST_PP_ITERATION() >
100 : public ParsedCommandOverloadBase
103 typedef boost::intrusive_ptr<ParsedCommandOverload> ptr;
104 typedef FunctionTraits traits;
105 typedef boost::function<typename traits::result_type(std::ostream &
106 mpp_TrailingArgTypes())> Function;
107 typedef void result_type;
109 # define mpp_l(z,n,d) \
110 typedef typename senf::remove_cvref< typename traits::mpp_ArgTypeN(n) >::type \
112 BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l, _ )
115 static ptr create(Function fn);
120 ParsedCommandOverload(Function fn);
122 virtual void v_execute(std::ostream & os, ParseCommandInfo const & command) const;
127 // ////////////////////////////////////////////////////////////////////////
128 #elif BOOST_PP_ITERATION_FLAGS()==2 // ////////////////////////////////////
129 // ////////////////////////////////////////////////////////////////////////
131 // inline template implementation (.cti)
133 template <class FunctionTraits, class ReturnValue>
134 prefix_ typename senf::console::ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION() >::ptr
135 senf::console::ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION() >::
138 return ptr(new ParsedCommandOverload(fn));
141 template <class FunctionTraits, class ReturnValue>
143 senf::console::ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION() >::
144 formatter(Formatter f)
149 template <class FunctionTraits, class ReturnValue>
151 senf::console::ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION()>::
152 ParsedCommandOverload(Function fn)
155 # define mpp_l(z,n,d) addParameter< mpp_ArgTypeN(n) >();
156 BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l, _ )
160 template <class FunctionTraits>
161 prefix_ typename senf::console::ParsedCommandOverload<FunctionTraits, void, BOOST_PP_ITERATION() >::ptr
162 senf::console::ParsedCommandOverload<FunctionTraits, void, BOOST_PP_ITERATION() >::
165 return ptr(new ParsedCommandOverload(fn));
168 template <class FunctionTraits>
170 senf::console::ParsedCommandOverload<FunctionTraits, void, BOOST_PP_ITERATION() >::
171 ParsedCommandOverload(Function fn)
174 # define mpp_l(z,n,d) addParameter< mpp_ArgTypeN(n) >();
175 BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l, _ )
179 // ////////////////////////////////////////////////////////////////////////
180 #elif BOOST_PP_ITERATION_FLAGS()==3 // ////////////////////////////////////
181 // ////////////////////////////////////////////////////////////////////////
183 // non-inline template implementation (.ct)
185 template <class FunctionTraits, class ReturnValue>
186 prefix_ void senf::console::ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION() >::
187 v_execute(std::ostream & os, ParseCommandInfo const & command)
190 if ( command.arguments().size() > BOOST_PP_ITERATION() )
191 throw SyntaxErrorException("invalid number of arguments");
192 int nDefaults ( BOOST_PP_ITERATION() - command.arguments().size() );
194 typedef typename boost::range_const_reverse_iterator<ParseCommandInfo::ArgumentsRange>::type
196 riterator i (boost::rbegin(command.arguments()));
197 riterator const i_end (boost::rend(command.arguments()));
199 # define mpp_l(z,n,d) \
200 mpp_ArgTypeN(n) mpp_ArgN(n) (arg< mpp_ArgTypeN(n) >( n ).defaultValue); \
201 if (! arg(n).hasDefault || nDefaults-- <= 0) { \
203 throw SyntaxErrorException("invalid number of arguments"); \
204 if (arg< mpp_ArgTypeN(n) >(n).parser) \
205 arg< mpp_ArgTypeN(n) >(n).parser( *(i++), mpp_ArgN(n) ); \
207 ArgumentTraits< mpp_ArgTypeN(n) >::parse( *(i++), mpp_ArgN(n) ); \
209 # define mpp_l_(z,n,d) mpp_l(z, BOOST_PP_SUB(BOOST_PP_DEC(BOOST_PP_ITERATION()), n), d)
210 BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l_, _ )
215 formatter_( function_(os mpp_TrailingArgs()), os );
217 ReturnValueTraits<result_type>::format( function_(os mpp_TrailingArgs()), os );
221 template <class FunctionTraits>
222 prefix_ void senf::console::ParsedCommandOverload<FunctionTraits, void, BOOST_PP_ITERATION() >::
223 v_execute(std::ostream & os, ParseCommandInfo const & command)
226 if ( command.arguments().size() > BOOST_PP_ITERATION() )
227 throw SyntaxErrorException("invalid number of arguments");
228 int nDefaults ( BOOST_PP_ITERATION() - command.arguments().size() );
230 typedef typename boost::range_const_reverse_iterator<ParseCommandInfo::ArgumentsRange>::type
232 riterator i (boost::rbegin(command.arguments()));
233 riterator const i_end (boost::rend(command.arguments()));
235 # define mpp_l(z,n,d) \
236 mpp_ArgTypeN(n) mpp_ArgN(n) (arg< mpp_ArgTypeN(n) >( n ).defaultValue); \
237 if (! arg(n).hasDefault || nDefaults-- <= 0) { \
239 throw SyntaxErrorException("invalid number of arguments"); \
240 if (arg< mpp_ArgTypeN(n) >(n).parser) \
241 arg< mpp_ArgTypeN(n) >(n).parser( *(i++), mpp_ArgN(n) ); \
243 ArgumentTraits< mpp_ArgTypeN(n) >::parse( *(i++), mpp_ArgN(n) ); \
245 # define mpp_l_(z,n,d) mpp_l(z, BOOST_PP_SUB(BOOST_PP_DEC(BOOST_PP_ITERATION()), n), d)
246 BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l_, _ )
250 function_(os mpp_TrailingArgs());
253 // ////////////////////////////////////////////////////////////////////////
254 #elif BOOST_PP_ITERATION_FLAGS()==4 // ////////////////////////////////////
255 // ////////////////////////////////////////////////////////////////////////
257 // CreateParsedCommandOverload
259 template <class Traits>
260 struct CreateParsedCommandOverload<Traits, true, BOOST_PP_ITERATION()>
262 typedef typename Traits::traits traits;
264 template <class Function>
265 static typename senf::console::ParsedCommandOverload<traits>::ptr create(Function fn)
267 return senf::console::ParsedCommandOverload<traits>::create(
268 boost::bind(fn mpp_TrailingBindArgs()) );
273 // ////////////////////////////////////////////////////////////////////////
274 #elif BOOST_PP_ITERATION_FLAGS()==5 // ////////////////////////////////////
275 // ////////////////////////////////////////////////////////////////////////
277 // Create keyword arg forwarding functions
279 template <BOOST_PP_ENUM_PARAMS( BOOST_PP_ITERATION(), class A ) >
280 next_type arg ( BOOST_PP_ENUM_BINARY_PARAMS( BOOST_PP_ITERATION(), A, const & a ),
281 typename arg_params::match< BOOST_PP_ENUM_PARAMS( BOOST_PP_ITERATION(), A ) >::type
282 kw = arg_params()) const {
283 return argInfo( kw(BOOST_PP_ENUM_PARAMS( BOOST_PP_ITERATION(), a )) );
286 // ////////////////////////////////////////////////////////////////////////
287 #endif // /////////////////////////////////////////////////////////////////
288 // ////////////////////////////////////////////////////////////////////////
289 // Undefine local Macros
291 #undef mpp_TrailingArgs
294 #undef mpp_TrailingArgTypes
300 // ////////////////////////////////////////////////////////////////////////
301 #endif // /////////////////////////////////////////////////////////////////
302 // ///////////////////////////mpp.e////////////////////////////////////////
308 // comment-column: 40
309 // c-file-style: "senf"
310 // indent-tabs-mode: nil
311 // ispell-local-dictionary: "american"
312 // compile-command: "scons -u test"