X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Console%2FParsedCommand.mpp;h=a1c5e466b69016d0f51dd7c242d5cc14f8b5dda7;hb=80c6cb7ba9ad7776824c84809f422209adf27331;hp=2aadffc50445627b1b610fff4f015505fe30ae9d;hpb=5209d7573f53f4b32730833af00668f5c0e56147;p=senf.git diff --git a/Console/ParsedCommand.mpp b/Console/ParsedCommand.mpp index 2aadffc..a1c5e46 100644 --- a/Console/ParsedCommand.mpp +++ b/Console/ParsedCommand.mpp @@ -29,12 +29,17 @@ // Custom includes #include #include +#include +#include #include #include +#include #include #include #include #include +#include +#include // ///////////////////////////mpp.p//////////////////////////////////////// #elif BOOST_PP_IS_ITERATING // //////////////////////////////////////////// @@ -44,10 +49,13 @@ #define mpp_ArgTypeN(n) BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(n)), _type) #define mpp_ArgN(n) BOOST_PP_CAT(arg, BOOST_PP_INC(n)) -#define mpp_ArgTypes_(z,n,d) typename traits::mpp_ArgTypeN(n) -#define mpp_TrailingArgTypes() BOOST_PP_ENUM_TRAILING( BOOST_PP_ITERATION(), mpp_ArgTypes_, _ ) +#define mpp_TrailingArgTypes_(z,n,d) typename traits::mpp_ArgTypeN(n) +#define mpp_TrailingArgTypes() BOOST_PP_ENUM_TRAILING( BOOST_PP_ITERATION(), mpp_TrailingArgTypes_, _ ) -#define mpp_Args_(z,n,d) boost::cref(mpp_ArgN(n)) +#define mpp_ArgTypes_(z,n,d) mpp_ArgTypeN(n) +#define mpp_ArgTypes() BOOST_PP_ENUM( BOOST_PP_ITERATION(), mpp_ArgTypes_, _ ) + +#define mpp_Args_(z,n,d) mpp_ArgN(n) #define mpp_TrailingArgs() BOOST_PP_ENUM_TRAILING( BOOST_PP_ITERATION(), mpp_Args_, _ ) #define mpp_BindArgs_(z,n,d) BOOST_PP_CAT( _, BOOST_PP_INC(BOOST_PP_INC(n))) @@ -59,8 +67,47 @@ // Header file (.hh) +template +class ParsedCommandOverload + : public ParsedCommandOverloadBase +{ +public: + typedef boost::intrusive_ptr ptr; + typedef FunctionTraits traits; + typedef boost::function Function; + typedef typename senf::remove_cvref::type result_type; + typedef boost::function Formatter; + +# define mpp_l(z,n,d) \ + typedef typename senf::remove_cvref< typename traits::mpp_ArgTypeN(n) >::type \ + mpp_ArgTypeN(n); + BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l, _ ) +# undef mpp_l + + typedef boost::mpl::vector< mpp_ArgTypes() > arg_types; + + static ptr create(Function fn); + + void formatter(Formatter f); + + using ParsedCommandOverloadBase::arg; + template + detail::ArgumentInfo::type> & arg() const; + +protected: + +private: + ParsedCommandOverload(Function fn); + + virtual void v_execute(std::ostream & os, ParseCommandInfo const & command) const; + + Function function_; + Formatter formatter_; +}; + template -class ParsedCommandOverload +class ParsedCommandOverload : public ParsedCommandOverloadBase { public: @@ -68,16 +115,22 @@ public: typedef FunctionTraits traits; typedef boost::function Function; + typedef void result_type; # define mpp_l(z,n,d) \ - typedef typename boost::remove_const< \ - typename boost::remove_reference< typename traits::mpp_ArgTypeN(n) >::type >::type \ - mpp_ArgTypeN(n); + typedef typename senf::remove_cvref< typename traits::mpp_ArgTypeN(n) >::type \ + mpp_ArgTypeN(n); BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l, _ ) # undef mpp_l + typedef boost::mpl::vector< mpp_ArgTypes() > arg_types; + static ptr create(Function fn); + using ParsedCommandOverloadBase::arg; + template + detail::ArgumentInfo::type> & arg() const; + protected: private: @@ -94,16 +147,72 @@ private: // inline template implementation (.cti) +template +prefix_ typename senf::console::ParsedCommandOverload::ptr +senf::console::ParsedCommandOverload:: +create(Function fn) +{ + return ptr(new ParsedCommandOverload(fn)); +} + +template +void +senf::console::ParsedCommandOverload:: +formatter(Formatter f) +{ + formatter_ = f; +} + +template +template +senf::console::detail::ArgumentInfo< + typename boost::mpl::at_c< + typename senf::console::ParsedCommandOverload< + FunctionTraits, ReturnValue, BOOST_PP_ITERATION()>::arg_types, + n>::type> & +senf::console::ParsedCommandOverload:: +arg() const +{ + return static_cast< detail::ArgumentInfo< + typename boost::mpl::at_c::type > & >(arg(n)); +} + +template +prefix_ +senf::console::ParsedCommandOverload:: +ParsedCommandOverload(Function fn) + : function_ (fn) +{ +# define mpp_l(z,n,d) addParameter< mpp_ArgTypeN(n) >(); + BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l, _ ) +# undef mpp_l +} + template -prefix_ typename senf::console::ParsedCommandOverload::ptr -senf::console::ParsedCommandOverload::create(Function fn) +prefix_ typename senf::console::ParsedCommandOverload::ptr +senf::console::ParsedCommandOverload:: +create(Function fn) { return ptr(new ParsedCommandOverload(fn)); } template +template +senf::console::detail::ArgumentInfo< + typename boost::mpl::at_c< + typename senf::console::ParsedCommandOverload< + FunctionTraits, void, BOOST_PP_ITERATION()>::arg_types, + n>::type> & +senf::console::ParsedCommandOverload:: +arg() const +{ + return static_cast< detail::ArgumentInfo< + typename boost::mpl::at_c::type > & >(arg(n)); +} + +template prefix_ -senf::console::ParsedCommandOverload:: +senf::console::ParsedCommandOverload:: ParsedCommandOverload(Function fn) : function_ (fn) { @@ -118,33 +227,72 @@ ParsedCommandOverload(Function fn) // non-inline template implementation (.ct) +template +prefix_ void senf::console::ParsedCommandOverload:: +v_execute(std::ostream & os, ParseCommandInfo const & command) + const +{ + if ( command.arguments().size() > BOOST_PP_ITERATION() ) + throw SyntaxErrorException("invalid number of arguments"); + int nDefaults ( BOOST_PP_ITERATION() - command.arguments().size() ); + + typedef typename boost::range_const_reverse_iterator::type + riterator; + riterator i (boost::rbegin(command.arguments())); + riterator const i_end (boost::rend(command.arguments())); + +# define mpp_l(z,n,d) \ + mpp_ArgTypeN(n) mpp_ArgN(n) (arg().defaultValue); \ + if (! arg(n).hasDefault || nDefaults-- <= 0) { \ + if (i == i_end) \ + throw SyntaxErrorException("invalid number of arguments"); \ + if (arg().parser) \ + arg().parser( *(i++), mpp_ArgN(n) ); \ + else \ + ArgumentTraits< mpp_ArgTypeN(n) >::parse( *(i++), mpp_ArgN(n) ); \ + } +# define mpp_l_(z,n,d) mpp_l(z, BOOST_PP_SUB(BOOST_PP_DEC(BOOST_PP_ITERATION()), n), d) + BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l_, _ ) +# undef mpp_l +# undef mpp_l_ + + if (formatter_) + formatter_( function_(os mpp_TrailingArgs()), os ); + else + ReturnValueTraits::format( function_(os mpp_TrailingArgs()), os ); + os << "\n"; +} + template -prefix_ void senf::console::ParsedCommandOverload:: +prefix_ void senf::console::ParsedCommandOverload:: v_execute(std::ostream & os, ParseCommandInfo const & command) const { - if ( command.arguments().size() > BOOST_PP_ITERATION() - || (command.arguments().size() < BOOST_PP_ITERATION() - && ! arg( command.arguments().size() ).hasDefault) ) + if ( command.arguments().size() > BOOST_PP_ITERATION() ) throw SyntaxErrorException("invalid number of arguments"); + int nDefaults ( BOOST_PP_ITERATION() - command.arguments().size() ); - ParseCommandInfo::argument_iterator i (command.arguments().begin()); - ParseCommandInfo::argument_iterator const i_end (command.arguments().end()); + typedef typename boost::range_const_reverse_iterator::type + riterator; + riterator i (boost::rbegin(command.arguments())); + riterator const i_end (boost::rend(command.arguments())); # define mpp_l(z,n,d) \ - mpp_ArgTypeN(n) mpp_ArgN(n) (arg< mpp_ArgTypeN(n) >( n ).defaultValue); \ - if (i != i_end) \ - detail::ParameterTraits< mpp_ArgTypeN(n) >::parse( *(i++), mpp_ArgN(n) ); - BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l, _ ) + mpp_ArgTypeN(n) mpp_ArgN(n) (arg().defaultValue); \ + if (! arg(n).hasDefault || nDefaults-- <= 0) { \ + if (i == i_end) \ + throw SyntaxErrorException("invalid number of arguments"); \ + if (arg().parser) \ + arg().parser( *(i++), mpp_ArgN(n) ); \ + else \ + ArgumentTraits< mpp_ArgTypeN(n) >::parse( *(i++), mpp_ArgN(n) ); \ + } +# define mpp_l_(z,n,d) mpp_l(z, BOOST_PP_SUB(BOOST_PP_DEC(BOOST_PP_ITERATION()), n), d) + BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l_, _ ) # undef mpp_l +# undef mpp_l_ - // Now call the function binding the arguments to the values parsed above. callAndWrite is - // specialized to ignore a 'void' return value but automatically write all other values to the - // output stream. - detail::ReturnValueTraits::callAndWrite( - boost::bind(function_, boost::ref(os) - mpp_TrailingArgs()), - os ); + function_(os mpp_TrailingArgs()); } // //////////////////////////////////////////////////////////////////////// @@ -156,7 +304,7 @@ v_execute(std::ostream & os, ParseCommandInfo const & command) template struct CreateParsedCommandOverload { - typedef Traits traits; + typedef typename Traits::traits traits; template static typename senf::console::ParsedCommandOverload::ptr create(Function fn) @@ -168,6 +316,19 @@ struct CreateParsedCommandOverload }; // //////////////////////////////////////////////////////////////////////// +#elif BOOST_PP_ITERATION_FLAGS()==5 // //////////////////////////////////// +// //////////////////////////////////////////////////////////////////////// + +// Create keyword arg forwarding functions + +template +next_type arg ( BOOST_PP_ENUM_BINARY_PARAMS( BOOST_PP_ITERATION(), A, const & a ), + typename arg_params::match< BOOST_PP_ENUM_PARAMS( BOOST_PP_ITERATION(), A ) >::type + kw = arg_params()) const { + return argInfo( kw(BOOST_PP_ENUM_PARAMS( BOOST_PP_ITERATION(), a )) ); +} + +// //////////////////////////////////////////////////////////////////////// #endif // ///////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////// // Undefine local Macros