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/cat.hpp>
33 #include <boost/preprocessor/arithmetic/inc.hpp>
34 #include <boost/preprocessor/repetition/repeat.hpp>
35 #include <boost/type_traits/remove_reference.hpp>
36 #include <boost/bind.hpp>
38 // ///////////////////////////mpp.p////////////////////////////////////////
39 #elif BOOST_PP_IS_ITERATING // ////////////////////////////////////////////
40 // ////////////////////////////////////////////////////////////////////////
43 #define mpp_ArgTypeN(n) BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(n)), _type)
44 #define mpp_ArgN(n) BOOST_PP_CAT(arg, BOOST_PP_INC(n))
46 #define mpp_ArgTypes_(z,n,d) typename traits::mpp_ArgTypeN(n)
47 #define mpp_TrailingArgTypes() BOOST_PP_ENUM_TRAILING( BOOST_PP_ITERATION(), mpp_ArgTypes_, _ )
49 #define mpp_Args_(z,n,d) boost::cref(mpp_ArgN(n))
50 #define mpp_TrailingArgs() BOOST_PP_ENUM_TRAILING( BOOST_PP_ITERATION(), mpp_Args_, _ )
52 #define mpp_BindArgs_(z,n,d) BOOST_PP_CAT( _, BOOST_PP_INC(BOOST_PP_INC(n)))
53 #define mpp_TrailingBindArgs() BOOST_PP_ENUM_TRAILING( BOOST_PP_ITERATION(), mpp_BindArgs_, _ )
55 // ////////////////////////////////////////////////////////////////////////
56 #if BOOST_PP_ITERATION_FLAGS()==1 // //////////////////////////////////////
57 // ////////////////////////////////////////////////////////////////////////
61 template <class FunctionTraits>
62 class ParsedCommandOverload<FunctionTraits, BOOST_PP_ITERATION() >
63 : public ParsedCommandOverloadBase
66 typedef boost::intrusive_ptr<ParsedCommandOverload> ptr;
67 typedef FunctionTraits traits;
68 typedef boost::function<typename traits::result_type(std::ostream &
69 mpp_TrailingArgTypes())> Function;
71 # define mpp_l(z,n,d) \
72 typedef typename boost::remove_reference<typename traits::mpp_ArgTypeN(n)>::type \
74 BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l, _ )
77 static ptr create(Function fn);
82 ParsedCommandOverload(Function fn);
84 virtual void v_execute(std::ostream & os, ParseCommandInfo const & command) const;
89 // ////////////////////////////////////////////////////////////////////////
90 #elif BOOST_PP_ITERATION_FLAGS()==2 // ////////////////////////////////////
91 // ////////////////////////////////////////////////////////////////////////
93 // inline template implementation (.cti)
95 template <class FunctionTraits>
96 prefix_ typename senf::console::ParsedCommandOverload<FunctionTraits, BOOST_PP_ITERATION() >::ptr
97 senf::console::ParsedCommandOverload<FunctionTraits, BOOST_PP_ITERATION() >::create(Function fn)
99 return ptr(new ParsedCommandOverload(fn));
102 template <class FunctionTraits>
104 senf::console::ParsedCommandOverload<FunctionTraits,BOOST_PP_ITERATION()>::
105 ParsedCommandOverload(Function fn)
108 # define mpp_l(z,n,d) addParameter< mpp_ArgTypeN(n) >();
109 BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l, _ )
113 // ////////////////////////////////////////////////////////////////////////
114 #elif BOOST_PP_ITERATION_FLAGS()==3 // ////////////////////////////////////
115 // ////////////////////////////////////////////////////////////////////////
117 // non-inline template implementation (.ct)
119 template <class FunctionTraits>
120 prefix_ void senf::console::ParsedCommandOverload<FunctionTraits, BOOST_PP_ITERATION() >::
121 v_execute(std::ostream & os, ParseCommandInfo const & command)
124 if ( command.arguments().size() > BOOST_PP_ITERATION()
125 || (command.arguments().size() < BOOST_PP_ITERATION()
126 && ! arg( BOOST_PP_ITERATION()-1 ).hasDefault) )
127 throw SyntaxErrorException("invalid number of arguments");
129 // First define local variables argN for the parameters. The variables are initialized to their
131 # define mpp_l(z,n,d) mpp_ArgTypeN(n) mpp_ArgN(n) (arg< mpp_ArgTypeN(n) >( n ).defaultValue);
132 BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l, _ )
135 ParseCommandInfo::argument_iterator i (command.arguments().begin());
136 ParseCommandInfo::argument_iterator const i_end (command.arguments().end());
138 // Now parse the arguments which are provided leaving the trailing arguments at their default
139 // value. We have already checked above, whether those default values are valid. Be aware, that
140 // the following cases do NOT have 'break' statements !
142 switch (BOOST_PP_ITERATION() - command.arguments().size()) {
144 # define mpp_l(z,n,d) \
146 detail::ParameterTraits< mpp_ArgTypeN(n) >::parse( *(i++), mpp_ArgN(n) );
147 BOOST_PP_REPEAT( BOOST_PP_ITERATION(), mpp_l, _ )
150 default : // This happens, if ALL arguments are defaulted
154 // Now call the function binding the arguments to the values parsed above. callAndWrite is
155 // specialized to ignore a 'void' return value but automatically write all other values to the
157 detail::ReturnValueTraits<typename traits::result_type>::callAndWrite(
158 boost::bind(function_, boost::ref(os)
163 // ////////////////////////////////////////////////////////////////////////
164 #elif BOOST_PP_ITERATION_FLAGS()==4 // ////////////////////////////////////
165 // ////////////////////////////////////////////////////////////////////////
167 // CreateParsedCommandOverload
169 template <class Traits>
170 struct CreateParsedCommandOverload<Traits, true, BOOST_PP_ITERATION()>
172 typedef Traits traits;
174 template <class Function>
175 static typename senf::console::ParsedCommandOverload<traits>::ptr create(Function fn)
177 return senf::console::ParsedCommandOverload<traits>::create(
178 boost::bind(fn mpp_TrailingBindArgs()) );
183 // ////////////////////////////////////////////////////////////////////////
184 #endif // /////////////////////////////////////////////////////////////////
185 // ////////////////////////////////////////////////////////////////////////
186 // Undefine local Macros
188 #undef mpp_TrailingArgs
191 #undef mpp_TrailingArgTypes
197 // ////////////////////////////////////////////////////////////////////////
198 #endif // /////////////////////////////////////////////////////////////////
199 // ///////////////////////////mpp.e////////////////////////////////////////
205 // comment-column: 40
206 // c-file-style: "senf"
207 // indent-tabs-mode: nil
208 // ispell-local-dictionary: "american"
209 // compile-command: "scons -u test"