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 inline template implementation */
26 #include "ParsedCommand.ih"
29 #include "../Utils/membind.hh"
30 #include <boost/format.hpp>
31 #include <boost/parameter/binding.hpp>
33 #define prefix_ inline
34 ///////////////////////////////cti.p///////////////////////////////////////
36 ///////////////////////////////////////////////////////////////////////////
37 // senf::console::ParsedCommandOverloadBase
40 prefix_ senf::console::detail::ParameterInfo<Type> &
41 senf::console::ParsedCommandOverloadBase::arg(unsigned n)
44 return dynamic_cast<detail::ParameterInfo<Type> &>(arg(n));
48 prefix_ void senf::console::ParsedCommandOverloadBase::addParameter()
50 parameters_.push_back(detail::ParameterInfo<Type>::create());
53 ///////////////////////////////////////////////////////////////////////////
54 // senf::console::ParsedCommandOverload<FunctionTraits,n>
56 #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, SENF_CONSOLE_MAX_COMMAND_ARITY, \
57 SENF_ABSOLUTE_INCLUDE_PATH(Console/ParsedCommand.mpp), \
59 #include BOOST_PP_ITERATE()
61 ///////////////////////////////////////////////////////////////////////////
62 // senf::console::ParsedCommandAttributorBase
65 prefix_ void senf::console::ParsedCommandAttributorBase::defaultValue(Type const & value)
68 overload().arg<Type>(index_).defaultValue = value;
69 overload().arg(index_).hasDefault = true;
72 ///////////////////////////////////////////////////////////////////////////
73 // senf::console::ParsedCommandAttributor<Overload>
75 template <class Overload>
76 prefix_ Overload & senf::console::ParsedCommandAttributor<Overload>::overload()
79 return static_cast<Overload &>(ParsedCommandAttributorBase::overload());
82 template <class Overload>
84 senf::console::ParsedCommandAttributor<Overload>::ParsedCommandAttributor(Overload & overload,
86 : ParsedCommandAttributorBase (overload, index)
89 ///////////////////////////////////////////////////////////////////////////
90 // senf::console::ParsedAttributeAttributorBase<Overload,Self>
92 template <class Overload, class Self>
94 senf::console::ParsedAttributeAttributorBase<Overload,Self>::doc(std::string const & doc)
97 this->ParsedCommandAttributorBase::nodeDoc(doc);
98 return static_cast<Self const &>(*this);
101 template <class Overload, class Self>
102 prefix_ Self senf::console::ParsedAttributeAttributorBase<Overload,Self>::
103 overloadDoc(std::string const & doc)
106 this->ParsedCommandAttributorBase::overloadDoc(doc);
107 return static_cast<Self const &>(*this);
110 template <class Overload, class Self>
112 senf::console::ParsedAttributeAttributorBase<Overload,Self>::
113 ParsedAttributeAttributorBase(Overload & overload, unsigned index)
114 : ParsedCommandAttributor<Overload> (overload, index)
117 ///////////////////////////////////////////////////////////////////////////
118 // senf::console::ParsedAttributeAttributor<Overload,index,flag>
120 template <class Overload, unsigned index, bool flag>
121 prefix_ typename senf::console::ParsedAttributeAttributor<Overload,index,flag>::next_type
122 senf::console::ParsedAttributeAttributor<Overload,index,flag>::arg()
128 template <class Overload, unsigned index, bool flag>
129 template <class ArgumentPack>
130 prefix_ typename senf::console::ParsedAttributeAttributor<Overload,index,flag>::next_type
131 senf::console::ParsedAttributeAttributor<Overload,index,flag>::
132 argInfo(ArgumentPack const & args)
135 # define HaveArg(tag) boost::is_same< \
136 typename boost::parameter::binding<ArgumentPack, tag>::type, void >()
138 argInfo( kw::name, args, HaveArg(kw::type::name) );
139 argInfo( kw::description, args, HaveArg(kw::type::description) );
140 argInfo( kw::default_value, args, HaveArg(kw::type::default_value) );
147 template <class Overload, unsigned index, bool flag>
148 template <class Kw, class ArgumentPack>
149 prefix_ void senf::console::ParsedAttributeAttributor<Overload,index,flag>::
150 argInfo(Kw const &, ArgumentPack const &, boost::mpl::true_)
154 template <class Overload, unsigned index, bool flag>
155 template <class ArgumentPack>
156 prefix_ void senf::console::ParsedAttributeAttributor<Overload,index,flag>::
157 argInfo(boost::parameter::keyword<kw::type::name> const &, ArgumentPack const & args,
161 this->argName(args[kw::name]);
164 template <class Overload, unsigned index, bool flag>
165 template <class ArgumentPack>
166 prefix_ void senf::console::ParsedAttributeAttributor<Overload,index,flag>::
167 argInfo(boost::parameter::keyword<kw::type::description> const &, ArgumentPack const & args,
171 this->argDoc(args[kw::description]);
174 template <class Overload, unsigned index, bool flag>
175 template <class ArgumentPack>
176 prefix_ void senf::console::ParsedAttributeAttributor<Overload,index,flag>::
177 argInfo(boost::parameter::keyword<kw::type::default_value> const &, ArgumentPack const & args,
181 this->defaultValue(args[kw::default_value]);
184 template <class Overload, unsigned index, bool flag>
186 senf::console::ParsedAttributeAttributor<Overload,index,flag>::
187 ParsedAttributeAttributor(Overload & overload)
188 : ParsedAttributeAttributorBase<Overload, ParsedAttributeAttributor> (overload, index)
191 template <class Overload, unsigned index, bool flag>
192 prefix_ typename senf::console::ParsedAttributeAttributor<Overload,index,flag>::next_type
193 senf::console::ParsedAttributeAttributor<Overload,index,flag>::next()
196 return ParsedAttributeAttributor<Overload, index+1>(this->overload());
199 template <class Overload, unsigned index, bool flag>
200 prefix_ void senf::console::ParsedAttributeAttributor<Overload,index,flag>::
201 defaultValue(value_type const & value)
204 ParsedCommandAttributorBase::defaultValue<arg_type>(value);
207 ///////////////////////////////////////////////////////////////////////////
208 // senf::console::ParsedAttributeAttributor<Overload, index, false>
210 template <class Overload, unsigned index>
212 senf::console::ParsedAttributeAttributor<Overload, index, false>::
213 ParsedAttributeAttributor(Overload & overload)
214 : ParsedAttributeAttributorBase< Overload,
215 ParsedAttributeAttributor<Overload, index, false> > (overload, index)
218 ///////////////////////////////////////////////////////////////////////////
223 // What is THIS about ??
225 // Ok, here's the dope: parsed commands may optionally have an std::ostream & first argument. If
226 // this argument is given, then the function will be called with the console output stream as
227 // it's first argument.
229 // This is implemented in the following way: ParsedCommandOverload (the class responsible for
230 // calling the callback) will ALWAYS pass the stream as first argument. If the user callback
231 // expects os as it's first argument, 'ignoreOneArg' will be false and the user supplied
232 // function will be directly passed to ParsedCommandOverload.
234 // If however, it does NOT take an std::ostream first argument, 'ignoreOneArg' will be true and
235 // the create member will use boost::bind to DROP the first argument.
237 template <class Traits, bool ignoreOneArg, unsigned arity=Traits::arity>
238 struct CreateParsedCommandOverload
241 template <class Traits, unsigned arity>
242 struct CreateParsedCommandOverload<Traits, false, arity>
244 typedef Traits traits;
246 template <class Function>
247 static typename senf::console::ParsedCommandOverload<traits>::ptr create(Function fn)
248 { return senf::console::ParsedCommandOverload<traits>::create(fn); };
251 # define BOOST_PP_ITERATION_PARAMS_1 (4, (0, SENF_CONSOLE_MAX_COMMAND_ARITY, \
252 SENF_ABSOLUTE_INCLUDE_PATH(Console/ParsedCommand.mpp), \
254 # include BOOST_PP_ITERATE()
258 template <class Function>
259 prefix_ senf::console::ParsedAttributeAttributor<
260 senf::console::ParsedCommandOverload<
261 typename senf::console::detail::ParsedCommandTraits<Function>::traits> >
262 senf::console::senf_console_add_node(DirectoryNode & node, std::string const & name,
265 OverloadedCommandNode & cmdNode (
267 ? dynamic_cast<OverloadedCommandNode &>(node(name))
268 : node.add(name, OverloadedCommandNode::create()) );
270 typedef detail::ParsedCommandTraits<Function> CmdTraits;
271 typedef ParsedCommandOverload<typename CmdTraits::traits> Overload;
272 typedef ParsedAttributeAttributor<Overload> Attributor;
275 cmdNode.add( CreateParsedCommandOverload<
276 typename CmdTraits::traits, ! CmdTraits::has_ostream_arg>::create(fn) ) );
279 template <class Owner, class Function>
280 prefix_ senf::console::ParsedAttributeAttributor<
281 senf::console::ParsedCommandOverload<
282 typename senf::console::detail::ParsedCommandTraits<Function>::traits> >
284 senf_console_add_node(DirectoryNode & node, Owner & owner, std::string const & name,
286 typename boost::enable_if_c<detail::ParsedCommandTraits<Function>::is_member>::type *)
288 OverloadedCommandNode & cmdNode (
290 ? dynamic_cast<OverloadedCommandNode &>(node(name))
291 : node.add(name, OverloadedCommandNode::create()) );
293 typedef detail::ParsedCommandTraits<Function> CmdTraits;
294 typedef ParsedCommandOverload<typename CmdTraits::traits> Overload;
295 typedef ParsedAttributeAttributor<Overload> Attributor;
298 cmdNode.add( CreateParsedCommandOverload<
299 typename CmdTraits::traits, ! CmdTraits::has_ostream_arg>::create(
300 senf::membind(fn,&owner)) ) );
303 ///////////////////////////////cti.e///////////////////////////////////////
310 // comment-column: 40
311 // c-file-style: "senf"
312 // indent-tabs-mode: nil
313 // ispell-local-dictionary: "american"
314 // compile-command: "scons -u test"