00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00026 #if !BOOST_PP_IS_ITERATING && !defined(MPP_ParsedCommand_)
00027 #define MPP_ParsedCommand_ 1
00028
00029
00030 #include <boost/preprocessor/iteration/iterate.hpp>
00031 #include <boost/preprocessor/repetition/enum_trailing.hpp>
00032 #include <boost/preprocessor/repetition/enum_params.hpp>
00033 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
00034 #include <boost/preprocessor/cat.hpp>
00035 #include <boost/preprocessor/arithmetic/inc.hpp>
00036 #include <boost/preprocessor/arithmetic/sub.hpp>
00037 #include <boost/preprocessor/repetition/repeat.hpp>
00038 #include <boost/type_traits/remove_reference.hpp>
00039 #include <boost/type_traits/remove_const.hpp>
00040 #include <boost/bind.hpp>
00041 #include <boost/mpl/vector.hpp>
00042 #include <boost/mpl/at.hpp>
00043 #include "senf/Utils/IgnoreValue.hh"
00044
00045
00046 #elif BOOST_PP_IS_ITERATING //-
00047 //-
00048 // Local Macros
00049
00050 #define mpp_ArgTypeN(n) BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(n)), _type)
00051 #define mpp_ArgN(n) BOOST_PP_CAT(arg, BOOST_PP_INC(n))
00052
00053 #define mpp_TrailingArgTypes_(z,n,d) typename traits::mpp_ArgTypeN(n)
00054 #define mpp_TrailingArgTypes() BOOST_PP_ENUM_TRAILING( BOOST_PP_ITERATION(), mpp_TrailingArgTypes_, _ )
00055
00056 #define mpp_ArgTypes_(z,n,d) mpp_ArgTypeN(n)
00057 #define mpp_ArgTypes() BOOST_PP_ENUM( BOOST_PP_ITERATION(), mpp_ArgTypes_, _ )
00058
00059 #define mpp_Args_(z,n,d) mpp_ArgN(n)
00060 #define mpp_TrailingArgs() BOOST_PP_ENUM_TRAILING( BOOST_PP_ITERATION(), mpp_Args_, _ )
00061
00062 #define mpp_BindArgs_(z,n,d) BOOST_PP_CAT( _, BOOST_PP_INC(BOOST_PP_INC(n)))
00063 #define mpp_TrailingBindArgs() BOOST_PP_ENUM_TRAILING( BOOST_PP_ITERATION(), mpp_BindArgs_, _ )
00064
00065
00066 #if BOOST_PP_ITERATION_FLAGS()==1 //-
00067 //-
00068
00069
00070
00071 template <class FunctionTraits, class ReturnValue>
00072 class ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION() >
00073 : public ParsedCommandOverloadBase
00074 {
00075 public:
00076 typedef boost::intrusive_ptr<ParsedCommandOverload> ptr;
00077 typedef FunctionTraits traits;
00078 typedef boost::function<typename traits::result_type(std::ostream &
00079 mpp_TrailingArgTypes())> Function;
00080 typedef typename senf::remove_cvref<typename traits::result_type>::type result_type;
00081 typedef boost::function<void (result_type const &, std::ostream &)> Formatter;
00082
00083 # define mpp_l(z,n,d) \
00084 typedef typename senf::remove_cvref< typename traits::mpp_ArgTypeN(n) >::type \
00085 mpp_ArgTypeN(n);
00086 BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l, _ )
00087 # undef mpp_l
00088
00089 typedef boost::mpl::vector< mpp_ArgTypes() > arg_types;
00090
00091 static ptr create(Function fn);
00092
00093 void formatter(Formatter f);
00094
00095 using ParsedCommandOverloadBase::arg;
00096 template <unsigned n>
00097 detail::ArgumentInfo<typename boost::mpl::at_c<arg_types, n>::type> & arg() const;
00098
00099 void function(Function fn);
00100
00101 protected:
00102
00103 private:
00104 ParsedCommandOverload(Function fn);
00105
00106 virtual void v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
00107 const;
00108
00109 Function function_;
00110 Formatter formatter_;
00111 };
00112
00113 template <class FunctionTraits>
00114 class ParsedCommandOverload<FunctionTraits, void, BOOST_PP_ITERATION() >
00115 : public ParsedCommandOverloadBase
00116 {
00117 public:
00118 typedef boost::intrusive_ptr<ParsedCommandOverload> ptr;
00119 typedef FunctionTraits traits;
00120 typedef boost::function<typename traits::result_type(std::ostream &
00121 mpp_TrailingArgTypes())> Function;
00122 typedef void result_type;
00123
00124 # define mpp_l(z,n,d) \
00125 typedef typename senf::remove_cvref< typename traits::mpp_ArgTypeN(n) >::type \
00126 mpp_ArgTypeN(n);
00127 BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l, _ )
00128 # undef mpp_l
00129
00130 typedef boost::mpl::vector< mpp_ArgTypes() > arg_types;
00131
00132 static ptr create(Function fn);
00133
00134 using ParsedCommandOverloadBase::arg;
00135 template <unsigned n>
00136 detail::ArgumentInfo<typename boost::mpl::at_c<arg_types, n>::type> & arg() const;
00137
00138 void function(Function fn);
00139
00140 protected:
00141
00142 private:
00143 ParsedCommandOverload(Function fn);
00144
00145 virtual void v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
00146 const;
00147
00148 Function function_;
00149 };
00150
00151
00152 #elif BOOST_PP_ITERATION_FLAGS()==2 //-
00153 //-
00154
00155
00156
00157 template <class FunctionTraits, class ReturnValue>
00158 prefix_ typename senf::console::ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION() >::ptr
00159 senf::console::ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION() >::
00160 create(Function fn)
00161 {
00162 return ptr(new ParsedCommandOverload(fn));
00163 }
00164
00165 template <class FunctionTraits, class ReturnValue>
00166 void
00167 senf::console::ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION() >::
00168 formatter(Formatter f)
00169 {
00170 formatter_ = f;
00171 }
00172
00173 template <class FunctionTraits, class ReturnValue>
00174 template <unsigned n>
00175 senf::console::detail::ArgumentInfo<
00176 typename boost::mpl::at_c<
00177 typename senf::console::ParsedCommandOverload<
00178 FunctionTraits, ReturnValue, BOOST_PP_ITERATION()>::arg_types,
00179 n>::type> &
00180 senf::console::ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION() >::
00181 arg() const
00182 {
00183 return static_cast< detail::ArgumentInfo<
00184 typename boost::mpl::at_c<arg_types, n>::type > & >(arg(n));
00185 }
00186
00187 template <class FunctionTraits, class ReturnValue>
00188 void
00189 senf::console::ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION() >::
00190 function(Function fn)
00191 {
00192 function_ = fn;
00193 }
00194
00195 template <class FunctionTraits, class ReturnValue>
00196 prefix_
00197 senf::console::ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION()>::
00198 ParsedCommandOverload(Function fn)
00199 : function_ (fn)
00200 {
00201 # define mpp_l(z,n,d) addParameter< mpp_ArgTypeN(n) >();
00202 BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l, _ )
00203 # undef mpp_l
00204 }
00205
00206 template <class FunctionTraits>
00207 prefix_ typename senf::console::ParsedCommandOverload<FunctionTraits, void, BOOST_PP_ITERATION() >::ptr
00208 senf::console::ParsedCommandOverload<FunctionTraits, void, BOOST_PP_ITERATION() >::
00209 create(Function fn)
00210 {
00211 return ptr(new ParsedCommandOverload(fn));
00212 }
00213
00214 template <class FunctionTraits>
00215 template <unsigned n>
00216 senf::console::detail::ArgumentInfo<
00217 typename boost::mpl::at_c<
00218 typename senf::console::ParsedCommandOverload<
00219 FunctionTraits, void, BOOST_PP_ITERATION()>::arg_types,
00220 n>::type> &
00221 senf::console::ParsedCommandOverload<FunctionTraits, void, BOOST_PP_ITERATION() >::
00222 arg() const
00223 {
00224 return static_cast< detail::ArgumentInfo<
00225 typename boost::mpl::at_c<arg_types, n>::type > & >(arg(n));
00226 }
00227
00228 template <class FunctionTraits>
00229 void
00230 senf::console::ParsedCommandOverload<FunctionTraits, void, BOOST_PP_ITERATION() >::
00231 function(Function fn)
00232 {
00233 function_ = fn;
00234 }
00235
00236 template <class FunctionTraits>
00237 prefix_
00238 senf::console::ParsedCommandOverload<FunctionTraits, void, BOOST_PP_ITERATION() >::
00239 ParsedCommandOverload(Function fn)
00240 : function_ (fn)
00241 {
00242 # define mpp_l(z,n,d) addParameter< mpp_ArgTypeN(n) >();
00243 BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l, _ )
00244 # undef mpp_l
00245 }
00246
00247
00248 #elif BOOST_PP_ITERATION_FLAGS()==3 //-
00249 //-
00250
00251
00252
00253 template <class FunctionTraits, class ReturnValue>
00254 prefix_ void senf::console::ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION() >::
00255 v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
00256 const
00257 {
00258
00259
00260 unsigned nArgs ( std::distance(command.arguments().begin(), command.arguments().end()) );
00261 if ( nArgs > BOOST_PP_ITERATION() )
00262 throw SyntaxErrorException("invalid number of arguments");
00263 int nDefaults ( BOOST_PP_ITERATION() - nArgs );
00264 senf::IGNORE( nDefaults );
00265
00266 typedef typename boost::range_reverse_iterator<const ParseCommandInfo::ArgumentsRange>::type
00267 riterator;
00268 riterator i (boost::rbegin(command.arguments()));
00269 riterator const i_end (boost::rend(command.arguments()));
00270
00271 # define mpp_l(z,n,d) \
00272 mpp_ArgTypeN(n) mpp_ArgN(n) (arg<n>().defaultValue); \
00273 if (! arg(n).hasDefault || nDefaults-- <= 0) { \
00274 if (i == i_end) \
00275 throw SyntaxErrorException("invalid number of arguments"); \
00276 if (arg<n>().parser) \
00277 arg<n>().parser( *(i++), mpp_ArgN(n) ); \
00278 else \
00279 ArgumentTraits< mpp_ArgTypeN(n) >::parse( *(i++), mpp_ArgN(n) ); \
00280 }
00281 # define mpp_l_(z,n,d) mpp_l(z, BOOST_PP_SUB(BOOST_PP_DEC(BOOST_PP_ITERATION()), n), d)
00282 BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l_, _ )
00283 # undef mpp_l
00284 # undef mpp_l_
00285
00286 ReturnValue rvv (function_(os mpp_TrailingArgs()));
00287 rv = rvv;
00288 if (formatter_)
00289 formatter_(rvv, os);
00290 else
00291 ReturnValueTraits<result_type>::format(rvv, os);
00292 os << "\n";
00293 }
00294
00295 template <class FunctionTraits>
00296 prefix_ void senf::console::ParsedCommandOverload<FunctionTraits, void, BOOST_PP_ITERATION() >::
00297 v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
00298 const
00299 {
00300
00301
00302 unsigned nArgs ( std::distance(command.arguments().begin(), command.arguments().end()) );
00303 if ( nArgs > BOOST_PP_ITERATION() )
00304 throw SyntaxErrorException("invalid number of arguments");
00305 int nDefaults ( BOOST_PP_ITERATION() - nArgs );
00306 senf::IGNORE( nDefaults );
00307
00308 typedef typename boost::range_reverse_iterator<const ParseCommandInfo::ArgumentsRange>::type
00309 riterator;
00310 riterator i (boost::rbegin(command.arguments()));
00311 riterator const i_end (boost::rend(command.arguments()));
00312
00313 # define mpp_l(z,n,d) \
00314 mpp_ArgTypeN(n) mpp_ArgN(n) (arg<n>().defaultValue); \
00315 if (! arg(n).hasDefault || nDefaults-- <= 0) { \
00316 if (i == i_end) \
00317 throw SyntaxErrorException("invalid number of arguments"); \
00318 if (arg<n>().parser) \
00319 arg<n>().parser( *(i++), mpp_ArgN(n) ); \
00320 else \
00321 ArgumentTraits< mpp_ArgTypeN(n) >::parse( *(i++), mpp_ArgN(n) ); \
00322 }
00323 # define mpp_l_(z,n,d) mpp_l(z, BOOST_PP_SUB(BOOST_PP_DEC(BOOST_PP_ITERATION()), n), d)
00324 BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l_, _ )
00325 # undef mpp_l
00326 # undef mpp_l_
00327
00328 function_(os mpp_TrailingArgs());
00329 }
00330
00331
00332 #elif BOOST_PP_ITERATION_FLAGS()==4 //-
00333 //-
00334
00335
00336
00337 template <class Traits>
00338 struct CreateParsedCommandOverload<Traits, true, BOOST_PP_ITERATION()>
00339 {
00340 typedef typename Traits::traits traits;
00341
00342 template <class Function>
00343 static typename senf::console::ParsedCommandOverload<traits>::ptr create(Function fn)
00344 {
00345 return senf::console::ParsedCommandOverload<traits>::create(
00346 boost::bind(fn mpp_TrailingBindArgs()) );
00347 }
00348
00349 };
00350
00351
00352 #elif BOOST_PP_ITERATION_FLAGS()==5 //-
00353 //-
00354
00355
00356
00357 template <BOOST_PP_ENUM_PARAMS( BOOST_PP_ITERATION(), class A ) >
00358 next_type arg ( BOOST_PP_ENUM_BINARY_PARAMS( BOOST_PP_ITERATION(), A, const & a ),
00359 typename arg_params::match< BOOST_PP_ENUM_PARAMS( BOOST_PP_ITERATION(), A ) >::type
00360 kw = arg_params()) {
00361 return argInfo( kw(BOOST_PP_ENUM_PARAMS( BOOST_PP_ITERATION(), a )) );
00362 }
00363
00364
00365 #endif //-
00366 //-
00367 // Undefine local Macros
00368
00369 #undef mpp_TrailingBindArgs
00370 #undef mpp_BindArgs_
00371
00372 #undef mpp_TrailingArgs
00373 #undef mpp_Args_
00374
00375 #undef mpp_ArgTypes
00376 #undef mpp_ArgTypes_
00377
00378 #undef mpp_TrailingArgTypes
00379 #undef mpp_TrailingArgTypes_
00380
00381 #undef mpp_ArgN
00382 #undef mpp_ArgTypeN
00383
00384
00385 #endif //-
00386 //-
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397