// $Id$ // // Copyright (C) 2008 // Fraunhofer Institute for Open Communication Systems (FOKUS) // // The contents of this file are subject to the Fraunhofer FOKUS Public License // Version 1.0 (the "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // http://senf.berlios.de/license.html // // The Fraunhofer FOKUS Public License Version 1.0 is based on, // but modifies the Mozilla Public License Version 1.1. // See the full license text for the amendments. // // Software distributed under the License is distributed on an "AS IS" basis, // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License // for the specific language governing rights and limitations under the License. // // The Original Code is Fraunhofer FOKUS code. // // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. // (registered association), Hansastraße 27 c, 80686 Munich, Germany. // // Contributor(s): // Stefan Bund /** \file \brief ParsedCommand Boost.Preprocesser external iteration include */ #if !BOOST_PP_IS_ITERATING && !defined(MPP_ParsedCommand_) #define MPP_ParsedCommand_ 1 // Custom includes #include #include #include #include #include #include #include #include #include #include #include #include #include #include "senf/Utils/IgnoreValue.hh" //-///////////////////////////mpp.p//////////////////////////////////////// #elif BOOST_PP_IS_ITERATING //-//////////////////////////////////////////// //-//////////////////////////////////////////////////////////////////////// // Local Macros #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_TrailingArgTypes_(z,n,d) typename traits::mpp_ArgTypeN(n) #define mpp_TrailingArgTypes() BOOST_PP_ENUM_TRAILING( BOOST_PP_ITERATION(), mpp_TrailingArgTypes_, _ ) #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))) #define mpp_TrailingBindArgs() BOOST_PP_ENUM_TRAILING( BOOST_PP_ITERATION(), mpp_BindArgs_, _ ) //-//////////////////////////////////////////////////////////////////////// #if BOOST_PP_ITERATION_FLAGS()==1 //-////////////////////////////////////// //-//////////////////////////////////////////////////////////////////////// // 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; void function(Function fn); protected: private: ParsedCommandOverload(Function fn); virtual void v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command) const; Function function_; Formatter formatter_; }; template class ParsedCommandOverload : public ParsedCommandOverloadBase { public: typedef boost::intrusive_ptr ptr; typedef FunctionTraits traits; typedef boost::function Function; typedef void result_type; # 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); using ParsedCommandOverloadBase::arg; template detail::ArgumentInfo::type> & arg() const; void function(Function fn); protected: private: ParsedCommandOverload(Function fn); virtual void v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command) const; Function function_; }; //-//////////////////////////////////////////////////////////////////////// #elif BOOST_PP_ITERATION_FLAGS()==2 //-//////////////////////////////////// //-//////////////////////////////////////////////////////////////////////// // 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 void senf::console::ParsedCommandOverload:: function(Function fn) { function_ = fn; } 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) { 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 void senf::console::ParsedCommandOverload:: function(Function fn) { function_ = fn; } 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 } //-//////////////////////////////////////////////////////////////////////// #elif BOOST_PP_ITERATION_FLAGS()==3 //-//////////////////////////////////// //-//////////////////////////////////////////////////////////////////////// // non-inline template implementation (.ct) template prefix_ void senf::console::ParsedCommandOverload:: v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command) const { // We NEED to know the number of arguments beforehand so we can assign default values // correctly ... hrmpf ... unsigned nArgs ( std::distance(command.arguments().begin(), command.arguments().end()) ); if ( nArgs > BOOST_PP_ITERATION() ) throw SyntaxErrorException("invalid number of arguments"); int nDefaults ( BOOST_PP_ITERATION() - nArgs ); senf::IGNORE( nDefaults ); typedef typename boost::range_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_ ReturnValue rvv (function_(os mpp_TrailingArgs())); rv = rvv; if (formatter_) formatter_(rvv, os); else ReturnValueTraits::format(rvv, os); os << "\n"; } template prefix_ void senf::console::ParsedCommandOverload:: v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command) const { // We NEED to know the number of arguments beforehand so we can assign default values // correctly ... hrmpf ... unsigned nArgs ( std::distance(command.arguments().begin(), command.arguments().end()) ); if ( nArgs > BOOST_PP_ITERATION() ) throw SyntaxErrorException("invalid number of arguments"); int nDefaults ( BOOST_PP_ITERATION() - nArgs ); senf::IGNORE( nDefaults ); typedef typename boost::range_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_ function_(os mpp_TrailingArgs()); } //-//////////////////////////////////////////////////////////////////////// #elif BOOST_PP_ITERATION_FLAGS()==4 //-//////////////////////////////////// //-//////////////////////////////////////////////////////////////////////// // CreateParsedCommandOverload template struct CreateParsedCommandOverload { typedef typename Traits::traits traits; template static typename senf::console::ParsedCommandOverload::ptr create(Function fn) { return senf::console::ParsedCommandOverload::create( boost::bind(fn mpp_TrailingBindArgs()) ); } }; //-//////////////////////////////////////////////////////////////////////// #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()) { return argInfo( kw(BOOST_PP_ENUM_PARAMS( BOOST_PP_ITERATION(), a )) ); } //-//////////////////////////////////////////////////////////////////////// #endif //-///////////////////////////////////////////////////////////////// //-//////////////////////////////////////////////////////////////////////// // Undefine local Macros #undef mpp_TrailingBindArgs #undef mpp_BindArgs_ #undef mpp_TrailingArgs #undef mpp_Args_ #undef mpp_ArgTypes #undef mpp_ArgTypes_ #undef mpp_TrailingArgTypes #undef mpp_TrailingArgTypes_ #undef mpp_ArgN #undef mpp_ArgTypeN //-//////////////////////////////////////////////////////////////////////// #endif //-///////////////////////////////////////////////////////////////// //-///////////////////////////mpp.e//////////////////////////////////////// // Local Variables: // mode: c++ // fill-column: 100 // comment-column: 40 // c-file-style: "senf" // indent-tabs-mode: nil // ispell-local-dictionary: "american" // compile-command: "scons -u test" // End: