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 template <class ArgumentPack>
122 prefix_ typename senf::console::ParsedAttributeAttributor<Overload,index,flag>::next_type
123 senf::console::ParsedAttributeAttributor<Overload,index,flag>::
124 argInfo(ArgumentPack const & args)
127 typedef typename boost::parameter::binding<
128 ArgumentPack, tag::detail::default_value_>::type default_value_t;
129 return argInfo( args, boost::is_same<default_value_t, void>() );
132 template <class Overload, unsigned index, bool flag>
133 template <class ArgumentPack>
134 prefix_ typename senf::console::ParsedAttributeAttributor<Overload,index,flag>::next_type
135 senf::console::ParsedAttributeAttributor<Overload,index,flag>::
136 argInfo(ArgumentPack const & args, boost::mpl::true_)
139 return argInfo( args[tag::name_ | ""],
140 args[tag::description_ | ""] );
144 template <class Overload, unsigned index, bool flag>
145 template <class ArgumentPack>
146 prefix_ typename senf::console::ParsedAttributeAttributor<Overload,index,flag>::next_type
147 senf::console::ParsedAttributeAttributor<Overload,index,flag>::
148 argInfo(ArgumentPack const & args, boost::mpl::false_)
151 return argInfo( args[tag::name_ | ""],
152 args[tag::description_ | ""],
153 args[tag::default_value_ | value_type()] );
156 template <class Overload, unsigned index, bool flag>
157 prefix_ typename senf::console::ParsedAttributeAttributor<Overload,index,flag>::next_type
158 senf::console::ParsedAttributeAttributor<Overload,index,flag>::argInfo(std::string const & name,
159 std::string const & doc)
167 template <class Overload, unsigned index, bool flag>
168 prefix_ typename senf::console::ParsedAttributeAttributor<Overload,index,flag>::next_type
169 senf::console::ParsedAttributeAttributor<Overload,index,flag>::argInfo(std::string const & name,
170 std::string const & doc,
171 value_type const & value)
180 template <class Overload, unsigned index, bool flag>
182 senf::console::ParsedAttributeAttributor<Overload,index,flag>::
183 ParsedAttributeAttributor(Overload & overload)
184 : ParsedAttributeAttributorBase<Overload, ParsedAttributeAttributor> (overload, index)
187 template <class Overload, unsigned index, bool flag>
188 prefix_ senf::console::ParsedAttributeAttributor<Overload, index+1>
189 senf::console::ParsedAttributeAttributor<Overload,index,flag>::next()
192 return ParsedAttributeAttributor<Overload, index+1>(this->overload());
195 template <class Overload, unsigned index, bool flag>
196 prefix_ void senf::console::ParsedAttributeAttributor<Overload,index,flag>::
197 defaultValue(value_type const & value)
200 ParsedCommandAttributorBase::defaultValue<arg_type>(value);
203 ///////////////////////////////////////////////////////////////////////////
204 // senf::console::ParsedAttributeAttributor<Overload, index, false>
206 template <class Overload, unsigned index>
208 senf::console::ParsedAttributeAttributor<Overload, index, false>::
209 ParsedAttributeAttributor(Overload & overload)
210 : ParsedCommandAttributor<Overload> (overload, index)
213 ///////////////////////////////////////////////////////////////////////////
218 // What is THIS about ??
220 // Ok, here's the dope: parsed commands may optionally have an std::ostream & first argument. If
221 // this argument is given, then the function will be called with the console output stream as
222 // it's first argument.
224 // This is implemented in the following way: ParsedCommandOverload (the class responsible for
225 // calling the callback) will ALWAYS pass the stream as first argument. If the user callback
226 // expects os as it's first argument, 'ignoreOneArg' will be false and the user supplied
227 // function will be directly passed to ParsedCommandOverload.
229 // If however, it does NOT take an std::ostream first argument, 'ignoreOneArg' will be true and
230 // the create member will use boost::bind to DROP the first argument.
232 template <class Traits, bool ignoreOneArg, unsigned arity=Traits::arity>
233 struct CreateParsedCommandOverload
236 template <class Traits, unsigned arity>
237 struct CreateParsedCommandOverload<Traits, false, arity>
239 typedef Traits traits;
241 template <class Function>
242 static typename senf::console::ParsedCommandOverload<traits>::ptr create(Function fn)
243 { return senf::console::ParsedCommandOverload<traits>::create(fn); };
246 # define BOOST_PP_ITERATION_PARAMS_1 (4, (0, SENF_CONSOLE_MAX_COMMAND_ARITY, \
247 SENF_ABSOLUTE_INCLUDE_PATH(Console/ParsedCommand.mpp), \
249 # include BOOST_PP_ITERATE()
253 template <class Function>
254 prefix_ senf::console::ParsedAttributeAttributor<
255 senf::console::ParsedCommandOverload<
256 typename senf::console::detail::ParsedCommandTraits<Function>::traits> >
257 senf::console::senf_console_add_node(DirectoryNode & node, std::string const & name,
260 OverloadedCommandNode & cmdNode (
262 ? dynamic_cast<OverloadedCommandNode &>(node(name))
263 : node.add(name, OverloadedCommandNode::create()) );
265 typedef detail::ParsedCommandTraits<Function> CmdTraits;
266 typedef ParsedCommandOverload<typename CmdTraits::traits> Overload;
267 typedef ParsedAttributeAttributor<Overload> Attributor;
270 cmdNode.add( CreateParsedCommandOverload<
271 typename CmdTraits::traits, ! CmdTraits::has_ostream_arg>::create(fn) ) );
274 template <class Owner, class Function>
275 prefix_ senf::console::ParsedAttributeAttributor<
276 senf::console::ParsedCommandOverload<
277 typename senf::console::detail::ParsedCommandTraits<Function>::traits> >
279 senf_console_add_node(DirectoryNode & node, Owner & owner, std::string const & name,
281 typename boost::enable_if_c<detail::ParsedCommandTraits<Function>::is_member>::type *)
283 OverloadedCommandNode & cmdNode (
285 ? dynamic_cast<OverloadedCommandNode &>(node(name))
286 : node.add(name, OverloadedCommandNode::create()) );
288 typedef detail::ParsedCommandTraits<Function> CmdTraits;
289 typedef ParsedCommandOverload<typename CmdTraits::traits> Overload;
290 typedef ParsedAttributeAttributor<Overload> Attributor;
293 cmdNode.add( CreateParsedCommandOverload<
294 typename CmdTraits::traits, ! CmdTraits::has_ostream_arg>::create(
295 senf::membind(fn,&owner)) ) );
298 ///////////////////////////////cti.e///////////////////////////////////////
305 // comment-column: 40
306 // c-file-style: "senf"
307 // indent-tabs-mode: nil
308 // ispell-local-dictionary: "american"
309 // compile-command: "scons -u test"