1d36bb441e694f3c0467a819f9f7d596bbf2002d
[senf.git] / senf / Utils / Console / ParsedCommand.cti
1 // $Id$
2 //
3 // Copyright (C) 2008
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
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.
12 //
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.
17 //
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.
22
23 /** \file
24     \brief ParsedCommand inline template implementation */
25
26 #include "ParsedCommand.ih"
27
28 // Custom includes
29 #include <senf/Utils/membind.hh>
30 #include <boost/format.hpp>
31 #include <senf/Utils/parameter.hh>
32
33 #define prefix_ inline
34 ///////////////////////////////cti.p///////////////////////////////////////
35
36 ///////////////////////////////////////////////////////////////////////////
37 // senf::console::detail::ArgumentInfo<ParameterType>
38
39 template <class ParameterType>
40 prefix_ typename senf::console::detail::ArgumentInfo<ParameterType>::ptr
41 senf::console::detail::ArgumentInfo<ParameterType>::create()
42 {
43     return ptr(new ArgumentInfo());
44 }
45
46 template <class ParameterType>
47 prefix_ senf::console::detail::ArgumentInfo<ParameterType>::ArgumentInfo()
48     : ArgumentInfoBase ( ArgumentTraits<ParameterType>::description(),
49                          ArgumentTraits<ParameterType>::singleToken ),
50       defaultValue ()
51 {}
52
53 template <class ParameterType>
54 prefix_ std::string senf::console::detail::ArgumentInfo<ParameterType>::defaultValueStr()
55     const
56 {
57     return hasDefault ? ArgumentTraits<ParameterType>::str(defaultValue) : "";
58 }
59
60 ///////////////////////////////////////////////////////////////////////////
61 // senf::console::ParsedCommandOverloadBase
62
63 template <class Type>
64 prefix_ void senf::console::ParsedCommandOverloadBase::addParameter()
65 {
66     parameters_.push_back(detail::ArgumentInfo<Type>::create());
67 }
68
69 ///////////////////////////////////////////////////////////////////////////
70 // senf::console::ParsedCommandOverload<FunctionTraits,n>
71
72 #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, SENF_CONSOLE_MAX_COMMAND_ARITY,                       \
73                                          SENF_ABSOLUTE_INCLUDE_PATH(Utils/Console/ParsedCommand.mpp),   \
74                                          2))
75 #include BOOST_PP_ITERATE()
76
77 ///////////////////////////////////////////////////////////////////////////
78 // senf::console::ParsedCommandAttributor<Overload>
79
80 template <class Overload>
81 prefix_ Overload & senf::console::ParsedCommandAttributor<Overload>::overload()
82     const
83 {
84     return static_cast<Overload &>(ParsedCommandAttributorBase::overload());
85 }
86
87 template <class Overload>
88 prefix_ senf::console::ParsedCommandAttributor<Overload>::
89 ParsedCommandAttributor(typename Overload::ptr overload, unsigned index)
90     : ParsedCommandAttributorBase (overload, index)
91 {}
92
93 template <class Overload>
94 prefix_ senf::console::ParsedCommandAttributor<Overload>::
95 ParsedCommandAttributor(ParsedCommandAttributorBase const & other, unsigned index)
96     : ParsedCommandAttributorBase (other, index)
97 {}
98
99 ///////////////////////////////////////////////////////////////////////////
100 // senf::console::ParsedArgumentAttributorBase<Overload,Self>
101
102 template <class Overload, class Self, class ReturnType>
103 prefix_ Self
104 senf::console::ParsedArgumentAttributorBase<Overload,Self,ReturnType>::doc(std::string const & doc)
105 {
106     this->ParsedCommandAttributorBase::nodeDoc(doc);
107     return static_cast<Self const &>(*this);
108 }
109
110 template <class Overload, class Self, class ReturnType>
111 prefix_ Self senf::console::ParsedArgumentAttributorBase<Overload,Self,ReturnType>::
112 shortdoc(std::string const & doc)
113 {
114     this->ParsedCommandAttributorBase::shortDoc(doc);
115     return static_cast<Self const &>(*this);
116 }
117
118 template <class Overload, class Self, class ReturnType>
119 prefix_ Self senf::console::ParsedArgumentAttributorBase<Overload,Self,ReturnType>::
120 overloadDoc(std::string const & doc)
121 {
122     this->ParsedCommandAttributorBase::overloadDoc(doc);
123     return static_cast<Self const &>(*this);
124 }
125
126 template <class Overload, class Self, class ReturnType>
127 prefix_ Self senf::console::ParsedArgumentAttributorBase<Overload,Self,ReturnType>::
128 formatter(typename Overload::Formatter f)
129 {
130     this->overload().formatter(f);
131     return static_cast<Self const &>(*this);
132 }
133
134 template <class Overload, class Self, class ReturnType>
135 prefix_
136 senf::console::ParsedArgumentAttributorBase<Overload,Self,ReturnType>::
137 ParsedArgumentAttributorBase(typename Overload::ptr overload, unsigned index)
138     : ParsedCommandAttributor<Overload> (overload, index)
139 {}
140
141 template <class Overload, class Self, class ReturnType>
142 prefix_
143 senf::console::ParsedArgumentAttributorBase<Overload,Self,ReturnType>::
144 ParsedArgumentAttributorBase(ParsedCommandAttributorBase const & other, unsigned index)
145     : ParsedCommandAttributor<Overload> (other, index)
146 {}
147
148 template <class Overload, class Self>
149 prefix_ Self
150 senf::console::ParsedArgumentAttributorBase<Overload,Self,void>::doc(std::string const & doc)
151 {
152     this->ParsedCommandAttributorBase::nodeDoc(doc);
153     return static_cast<Self const &>(*this);
154 }
155
156 template <class Overload, class Self>
157 prefix_ Self senf::console::ParsedArgumentAttributorBase<Overload, Self, void>::
158 shortdoc(std::string const & doc)
159 {
160     this->ParsedCommandAttributorBase::shortDoc(doc);
161     return static_cast<Self const &>(*this);
162 }
163
164 template <class Overload, class Self>
165 prefix_ Self senf::console::ParsedArgumentAttributorBase<Overload,Self,void>::
166 overloadDoc(std::string const & doc)
167 {
168     this->ParsedCommandAttributorBase::overloadDoc(doc);
169     return static_cast<Self const &>(*this);
170 }
171
172 template <class Overload, class Self>
173 prefix_
174 senf::console::ParsedArgumentAttributorBase<Overload, Self, void>::
175 ParsedArgumentAttributorBase(typename Overload::ptr overload, unsigned index)
176     : ParsedCommandAttributor<Overload> (overload, index)
177 {}
178
179 template <class Overload, class Self>
180 prefix_
181 senf::console::ParsedArgumentAttributorBase<Overload, Self, void>::
182 ParsedArgumentAttributorBase(ParsedCommandAttributorBase const & other, unsigned index)
183     : ParsedCommandAttributor<Overload> (other, index)
184 {}
185
186 ///////////////////////////////////////////////////////////////////////////
187 // senf::console::ParsedArgumentAttributor<Overload,index,flag>
188
189 template <class Overload, unsigned index, bool flag>
190 prefix_ typename senf::console::ParsedArgumentAttributor<Overload,index,flag>::next_type
191 senf::console::ParsedArgumentAttributor<Overload,index,flag>::arg()
192     const
193 {
194     return next();
195 }
196
197 template <class Overload, unsigned index, bool flag>
198 template <class ArgumentPack>
199 prefix_ typename senf::console::ParsedArgumentAttributor<Overload,index,flag>::next_type
200 senf::console::ParsedArgumentAttributor<Overload,index,flag>::
201 argInfo(ArgumentPack const & args)
202 {
203 #   define ProcessArg(tag) \
204         argInfo( kw:: tag, args, senf::has_parameter< ArgumentPack, kw::type:: tag >() )
205
206     ProcessArg(name);
207     ProcessArg(description);
208     ProcessArg(default_value);
209     ProcessArg(type_name);
210     ProcessArg(default_doc);
211     ProcessArg(parser);
212
213     return next();
214
215 #   undef ProcessArg
216 }
217
218 template <class Overload, unsigned index, bool flag>
219 template <class Kw, class ArgumentPack>
220 prefix_ void senf::console::ParsedArgumentAttributor<Overload,index,flag>::
221 argInfo(Kw const &, ArgumentPack const &, boost::mpl::false_)
222 {}
223
224 template <class Overload, unsigned index, bool flag>
225 template <class ArgumentPack>
226 prefix_ void senf::console::ParsedArgumentAttributor<Overload,index,flag>::
227 argInfo(boost::parameter::keyword<kw::type::name> const &, ArgumentPack const & args,
228         boost::mpl::true_)
229 {
230     this->argName(args[kw::name]);
231 }
232
233 template <class Overload, unsigned index, bool flag>
234 template <class ArgumentPack>
235 prefix_ void senf::console::ParsedArgumentAttributor<Overload,index,flag>::
236 argInfo(boost::parameter::keyword<kw::type::description> const &, ArgumentPack const & args,
237         boost::mpl::true_)
238 {
239     this->argDoc(args[kw::description]);
240 }
241
242 template <class Overload, unsigned index, bool flag>
243 template <class ArgumentPack>
244 prefix_ void senf::console::ParsedArgumentAttributor<Overload,index,flag>::
245 argInfo(boost::parameter::keyword<kw::type::default_value> const &, ArgumentPack const & args,
246         boost::mpl::true_)
247 {
248     this->defaultValue(args[kw::default_value]);
249 }
250
251 template <class Overload, unsigned index, bool flag>
252 template <class ArgumentPack>
253 prefix_ void senf::console::ParsedArgumentAttributor<Overload,index,flag>::
254 argInfo(boost::parameter::keyword<kw::type::type_name> const &, ArgumentPack const & args,
255         boost::mpl::true_)
256 {
257     this->typeName(args[kw::type_name]);
258 }
259
260 template <class Overload, unsigned index, bool flag>
261 template <class ArgumentPack>
262 prefix_ void senf::console::ParsedArgumentAttributor<Overload,index,flag>::
263 argInfo(boost::parameter::keyword<kw::type::default_doc> const &, ArgumentPack const & args,
264         boost::mpl::true_)
265 {
266     BOOST_STATIC_ASSERT(( senf::has_parameter<ArgumentPack, kw::type::default_value>::value ));
267     this->defaultDoc(args[kw::default_doc]);
268 }
269
270 template <class Overload, unsigned index, bool flag>
271 template <class ArgumentPack>
272 prefix_ void senf::console::ParsedArgumentAttributor<Overload,index,flag>::
273 argInfo(boost::parameter::keyword<kw::type::parser> const &, ArgumentPack const & args,
274         boost::mpl::true_)
275 {
276     this->parser(args[kw::parser]);
277 }
278
279 template <class Overload, unsigned index, bool flag>
280 prefix_ senf::console::ParsedArgumentAttributor<Overload,index,flag>::
281 ParsedArgumentAttributor(typename Overload::ptr overload)
282 : ParsedArgumentAttributorBase<Overload, ParsedArgumentAttributor> (overload, index)
283 {}
284
285 template <class Overload, unsigned index, bool flag>
286 prefix_ senf::console::ParsedArgumentAttributor<Overload,index,flag>::
287 ParsedArgumentAttributor(ParsedCommandAttributorBase const & other)
288     : ParsedArgumentAttributorBase<Overload, ParsedArgumentAttributor> (other, index)
289 {}
290
291 template <class Overload, unsigned index, bool flag>
292 prefix_ typename senf::console::ParsedArgumentAttributor<Overload,index,flag>::next_type
293 senf::console::ParsedArgumentAttributor<Overload,index,flag>::next()
294     const
295 {
296     return ParsedArgumentAttributor<Overload, index+1>(*this);
297 }
298
299 template <class Overload, unsigned index, bool flag>
300 prefix_ void senf::console::ParsedArgumentAttributor<Overload,index,flag>::
301 defaultValue(value_type const & value)
302 {
303     this->overload().arg<index>().defaultValue = value;
304     this->overload().arg(index).hasDefault = true;
305 }
306
307 template <class Overload, unsigned index, bool flag>
308 template <class Fn>
309 prefix_ void senf::console::ParsedArgumentAttributor<Overload,index,flag>::parser(Fn fn)
310 {
311     this->overload().arg<index>().parser = fn;
312 }
313
314 ///////////////////////////////////////////////////////////////////////////
315 // senf::console::ParsedArgumentAttributor<Overload, index, false>
316
317 template <class Overload, unsigned index>
318 prefix_
319 senf::console::ParsedArgumentAttributor<Overload, index, false>::
320 ParsedArgumentAttributor(typename Overload::ptr overload)
321     : ParsedArgumentAttributorBase<
322           Overload, ParsedArgumentAttributor<Overload, index, false> > (overload, index)
323 {}
324
325 template <class Overload, unsigned index>
326 prefix_
327 senf::console::ParsedArgumentAttributor<Overload, index, false>::
328 ParsedArgumentAttributor(ParsedCommandAttributorBase const & other)
329     : ParsedArgumentAttributorBase<Overload, ParsedArgumentAttributor> (other, index)
330 {}
331
332 ///////////////////////////////////////////////////////////////////////////
333 // namespace members
334
335 namespace senf {
336 namespace console {
337 namespace detail {
338
339 #ifndef DOXYGEN
340
341     struct ParsedCommandAddNodeAccess
342     {
343         template <class Attributor, class NodePtr>
344         static Attributor attributor(NodePtr ptr)
345             { return Attributor(ptr); }
346     };
347
348     template <class Signature, class Fn>
349     typename senf::console::detail::ParsedCommandTraits<Signature>::Attributor
350     addOverloadedCommandNode(Fn fn)
351     {
352         typedef senf::console::detail::ParsedCommandTraits<Signature> CmdTraits;
353         typedef senf::console::ParsedCommandOverload<typename CmdTraits::traits> Overload;
354         typedef senf::console::ParsedArgumentAttributor<Overload> Attributor;
355
356         return detail::ParsedCommandAddNodeAccess::attributor<Attributor>(
357             CreateParsedCommandOverload<CmdTraits>::create(fn));
358     }
359
360 #endif
361
362 }}}
363
364 ///////////////////////////////////////////////////////////////////////////
365
366 template <class Signature>
367 prefix_ senf::console::SimpleOverloadAttributor
368 senf::console::factory::
369 Command(boost::function<Signature> fn,
370         typename boost::enable_if_c<detail::ParsedCommandTraits<Signature>::is_simple>::type *)
371 {
372     return SimpleOverloadAttributor(fn);
373 }
374
375 template <class Function>
376 prefix_ senf::console::SimpleOverloadAttributor
377 senf::console::factory::
378 Command(Function fn,
379         typename boost::enable_if_c<detail::ParsedCommandTraits<Function>::is_simple>::type *)
380 {
381     return SimpleOverloadAttributor(fn);
382 }
383
384 template <class Owner, class Member>
385 prefix_ senf::console::SimpleOverloadAttributor
386 senf::console::factory::
387 Command(Member memfn, Owner * owner,
388         typename boost::enable_if<boost::is_member_function_pointer<Member> >::type *,
389         typename boost::enable_if_c<detail::ParsedCommandTraits<Member>::is_simple>::type *)
390 {
391     return SimpleOverloadAttributor(senf::membind(memfn,owner));
392 }
393
394 template <class Owner, class Member>
395 prefix_ senf::console::SimpleOverloadAttributor
396 senf::console::factory::
397 Command(Member memfn, Owner const * owner,
398         typename boost::enable_if<boost::is_member_function_pointer<Member> >::type *,
399         typename boost::enable_if_c<detail::ParsedCommandTraits<Member>::is_simple>::type *)
400 {
401     return SimpleOverloadAttributor(senf::membind(memfn,owner));
402 }
403
404 template <class CastTo, class Signature>
405 prefix_ typename senf::console::detail::ParsedCommandTraits<CastTo>::Attributor
406 senf::console::factory::
407 Command(boost::function<Signature> fn)
408 {
409     return detail::addOverloadedCommandNode<CastTo>(fn);
410 }
411
412 template <class CastTo, class Function>
413 prefix_ typename senf::console::detail::ParsedCommandTraits<CastTo>::Attributor
414 senf::console::factory::
415 Command(Function fn,
416         typename boost::enable_if_c<detail::ParsedCommandTraits<Function>::is_callable>::type *,
417         typename boost::disable_if<boost::is_member_function_pointer<Function> >::type *)
418 {
419     return detail::addOverloadedCommandNode<CastTo>(fn);
420 }
421
422 template <class Signature>
423 prefix_ typename senf::console::detail::ParsedCommandTraits<Signature>::Attributor
424 senf::console::factory::
425 Command(boost::function<Signature> fn)
426 {
427     return detail::addOverloadedCommandNode<Signature>(fn);
428 }
429
430 template <class Function>
431 prefix_ typename senf::console::detail::ParsedCommandTraits<Function>::Attributor
432 senf::console::factory::
433 Command(Function fn,
434         typename boost::enable_if_c<detail::ParsedCommandTraits<Function>::is_callable>::type *,
435         typename boost::disable_if<boost::is_member_function_pointer<Function> >::type *)
436 {
437     return detail::addOverloadedCommandNode<Function>(fn);
438 }
439
440 template <class Owner, class Member>
441 prefix_ typename senf::console::detail::ParsedCommandTraits<Member>::Attributor
442 senf::console::factory::
443 Command(Member memfn, Owner * owner,
444              typename boost::enable_if<boost::is_member_function_pointer<Member> >::type *)
445 {
446     return detail::addOverloadedCommandNode<Member>(senf::membind(memfn,owner));
447 }
448
449 template <class Owner, class Member>
450 prefix_ typename senf::console::detail::ParsedCommandTraits<Member>::Attributor
451 senf::console::factory::
452 Command(Member memfn, Owner const * owner,
453              typename boost::enable_if<boost::is_member_function_pointer<Member> >::type *)
454 {
455     return detail::addOverloadedCommandNode<Member>(senf::membind(memfn,owner));
456 }
457
458 template <class CastTo, class Owner, class Member>
459 prefix_ typename senf::console::detail::ParsedCommandTraits<CastTo>::Attributor
460 senf::console::factory::
461 Command(Member memfn, Owner * owner,
462              typename boost::enable_if<boost::is_member_function_pointer<Member> >::type *)
463 {
464     return detail::addOverloadedCommandNode<CastTo>(senf::membind(memfn,owner));
465 }
466
467 template <class CastTo, class Owner, class Member>
468 prefix_ typename senf::console::detail::ParsedCommandTraits<CastTo>::Attributor
469 senf::console::factory::
470 Command(Member memfn, Owner const * owner,
471              typename boost::enable_if<boost::is_member_function_pointer<Member> >::type *)
472 {
473     return detail::addOverloadedCommandNode<CastTo>(senf::membind(memfn,owner));
474 }
475
476 ///////////////////////////////cti.e///////////////////////////////////////
477 #undef prefix_
478
479 \f
480 // Local Variables:
481 // mode: c++
482 // fill-column: 100
483 // comment-column: 40
484 // c-file-style: "senf"
485 // indent-tabs-mode: nil
486 // ispell-local-dictionary: "american"
487 // compile-command: "scons -u test"
488 // End: