Documentation updates/fixes
[senf.git] / senf / Utils / Console / ParsedCommand.hh
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 public header */
25
26 #ifndef HH_SENF_Scheduler_Console_ParsedCommand_
27 #define HH_SENF_Scheduler_Console_ParsedCommand_ 1
28
29 // Custom includes
30
31 #define BOOST_PARAMETER_MAX_ARITY 6
32
33 #include <vector>
34 #include <boost/type_traits/function_traits.hpp>
35 #include <boost/type_traits/is_member_function_pointer.hpp>
36 #include <boost/mpl/if.hpp>
37 #include <boost/utility.hpp>
38 #include <boost/parameter/keyword.hpp>
39 #include <boost/parameter/parameters.hpp>
40 #include <senf/config.hh>
41 #include "OverloadedCommand.hh"
42 #include "Traits.hh"
43 #include <senf/Utils/type_traits.hh>
44
45 #include "ParsedCommand.ih"
46 #include "ParsedCommand.mpp"
47 ///////////////////////////////hh.p////////////////////////////////////////
48
49 namespace senf {
50 namespace console {
51
52     namespace detail { class ArgumentInfoBase; }
53
54     /** \brief CommandOverload implementation with automatic argument parsing
55
56         ParsedCommandOverloadBase implements a CommandOverload implementation supporting automatic
57         parsing of arguments. This is \e not a node, it's a CommandOverload which is then added to
58         an OverloadedCommandNode instance.
59
60         Automatic argument parsing and return value processing consists of several components:
61         \li \ref overload_add Adding overload instances to the tree
62         \li (Advanced) \ref overload_parse
63         \li (Advanced) \ref overload_format
64
65         \section overload_add Adding argument parsing callbacks to the tree
66
67         To add overloads to the tree, use the senf::console::factory::Command factory:
68         \code
69         namespace fty = senf::console::factory;
70
71         std::string taskStatus(int id);
72
73         senf::console::root().add("taskStatus", fty::Command(&taskStatus));
74         \endcode
75
76         There are quite a number of additional parameters available to be set. These parameters are
77         documented in ParsedArgumentAttributor. Parameters are set by adding them as additional
78         calls after adding the node:
79
80         \code
81         senf::console::root().add("taskStatus", fty::Command(&taskStatus)
82             .doc("Query the current task status")
83             .arg( name = "id",
84                   description = "numeric id of task to check, -1 for the current task."
85                   default_value = -1 ) );
86         \endcode
87
88         You may also add an additional \c std::ostream & Argument as first argument to the
89         callback. If this argument is present, the stream connected to the console which issued the
90         command will be passed there. This allows writing arbitrary messages to the console.
91
92         Additionally, overloading is supported by registering multiple commands under the same
93         name. So, elaborating on above example:
94         \code
95         std::string taskStatus(int id);
96         std::string taskStatus(std::string const & name);
97
98         senf::console::root()
99             .add("taskStatus", fty::Command(static_cast<std::string (*)(int)>(
100                                                 &taskStatus))
101             .doc("Query the current task status")
102             .overloadDoc("Query status by id")
103             .arg( name = "id",
104                   description = "numeric id of task to check, -1 for the current task."
105                   default_value = -1 ) );
106         senf::console::root()
107             .add("taskStatus", fty::Commande(static_cast<std::string (*)(std::string const &)>(
108                                                  &taskStatus))
109             .overloadDoc("Query status by name")
110             .arg( name = "name",
111                   description = "name of task to check" ) );
112         \endcode
113
114         We can see here, that taking the address of an overloaded function requires a cast. If you
115         can give unique names to each of the C++ overloads (not the overloads in the console), you
116         should do so to make the unwieldy casts unnecessary.
117
118         \section overload_parse Custom parameter parsers
119
120         By default, parameters are parsed using \c boost::lexical_cast and therefore using \c
121         iostreams. This means, that any type which can be read from a stream can automatically be
122         used as argument type.
123
124         However, argument parsing can be configured by specializing
125         senf::console::ArgumentTraits. See that class for more information.
126
127         \section overload_format Custom return-value formatters
128
129         By default, return values are streamed to an ostream. This automatically allows any
130         streamable type to be used as return value. To add new types or customize the formating, the
131         senf::console::ReturnValueTraits template needs to be specialized for that type. See
132         that class for more information.
133
134         \ingroup console_commands
135      */
136     class ParsedCommandOverloadBase
137         : public CommandOverload
138     {
139     public:
140         typedef boost::intrusive_ptr<ParsedCommandOverloadBase> ptr;
141
142         detail::ArgumentInfoBase & arg(unsigned n) const;
143
144         void doc(std::string const & d);
145
146     protected:
147         ParsedCommandOverloadBase();
148
149         template <class Type> void addParameter();
150
151     private:
152         virtual unsigned v_numArguments() const;
153         virtual void v_argumentDoc(unsigned index, ArgumentDoc & doc) const;
154         virtual std::string v_doc() const;
155
156         typedef std::vector<detail::ArgumentInfoBase::ptr> Parameters;
157         Parameters parameters_;
158         std::string doc_;
159     };
160
161     /** \brief Parsed command overload
162
163         ParsedCommandOverload provides the command overload added to an OverloadedCommandNode for an
164         automatically parsed command.
165
166         This class is normally instantiated automatically when adding a function or member-function
167         pointer as callback to the tree. Manually instantiation this type of overload is \e not
168         simple, since the function signature has to be manipulated correctly to support the optional
169         \c std::ostream first argument.
170
171         \implementation This class is specialized for each supported number of command arguments.
172
173         \todo Implement automatic binding of member functions for parser and formatter
174      */
175     template <class FunctionTraits, class ReturnType, unsigned arity>
176     class ParsedCommandOverload : public ParsedCommandOverloadBase
177     {
178     public:
179         typedef boost::intrusive_ptr<ParsedCommandOverload> ptr;
180     };
181
182 #ifndef DOXYGEN
183
184 #   define BOOST_PP_ITERATION_PARAMS_1                                  \
185         (4, (0, SENF_CONSOLE_MAX_COMMAND_ARITY,                         \
186              SENF_ABSOLUTE_INCLUDE_PATH(Utils/Console/ParsedCommand.mpp), \
187              1))
188 #   include BOOST_PP_ITERATE()
189
190 #endif
191
192     /** \brief Generic ParsedCommandOverloadBase attributes
193
194         Attributes for parsed commands are not set directly on the node. They are set via a special
195         attributor temporary returned when adding a parsed command to the tree.
196
197         This class is the base class for those attributors. It provides members which do not depend
198         in any way on the exact type of command added.
199
200         \see \ref console_autoparse
201      */
202     class ParsedCommandAttributorBase
203         : public detail::NodeFactory
204     {
205     public:
206         typedef OverloadedCommandNode node_type;
207         typedef OverloadedCommandNode & result_type;
208
209     protected:
210         ParsedCommandAttributorBase(ParsedCommandOverloadBase::ptr overload, unsigned index);
211         ParsedCommandAttributorBase(ParsedCommandAttributorBase const & other, unsigned index);
212
213         void argName(std::string const & name);
214         void argDoc(std::string const & doc);
215         void typeName(std::string const & doc);
216         void defaultDoc(std::string const & doc);
217
218         ParsedCommandOverloadBase & overload() const;
219         void overloadDoc(std::string const & doc);
220         void nodeDoc(std::string const & doc);
221         void shortDoc(std::string const & doc);
222
223     private:
224         OverloadedCommandNode & create(DirectoryNode & dir, std::string const & name) const;
225
226         ParsedCommandOverloadBase::ptr overload_;
227         unsigned index_;
228         boost::optional<std::string> doc_;
229         boost::optional<std::string> shortdoc_;
230
231         friend class senf::console::DirectoryNode;
232     };
233
234     /** \brief Non argument dependent ParsedCommandBase attributes
235
236         Attributes for parsed commands are not set directly on the node. They are set via a special
237         attributor temporary returned when adding a parsed command to the tree.
238
239         This class adds all those members, which do depend on the type of command added (and thereby
240         on that commands signature) but do not depend on the type of any single argument.
241
242         \see \ref console_autoparse
243      */
244     template <class Overload>
245     class ParsedCommandAttributor
246         : public ParsedCommandAttributorBase
247     {
248     public:
249         Overload & overload() const;    ///< Get the command overload
250
251     protected:
252         ParsedCommandAttributor(typename Overload::ptr overload, unsigned index);
253         ParsedCommandAttributor(ParsedCommandAttributorBase const & other, unsigned index);
254
255     private:
256     };
257
258     /** \brief Keyword argument tags
259
260         The tags defined in this namespace are used as keyword arguments via the <a
261         href="http://www.boost.org/doc/libs/1_33_1/libs/parameter/doc/html/index.html">Boost.Parameter</a>
262         library.
263
264         For the keyword tags, the standard C++ scoping rules apply
265         \code
266         namespace fty=senf::console::factory;
267
268         // Either qualify them with their complete namespace
269         dir.add(..., fty::Command(...)
270             .arg( senf::console::kw::name = "name" ) );
271
272         // Or use a namespace alias
273         namespace kw = senf::console::kw;
274         dir.add(..., fty::Command(...)
275             .arg( kw::name = "name" ) );
276
277         // Or import the keywords into the current namespace (beware of name collisions)
278         using namespace senf::console::kw;
279         dir.add(..., fty::Command(...)
280             .arg( name = "name" ) );
281         \endcode
282
283         The second alternative is preferred, the <tt>using namespace</tt> directive may be used as
284         long as the keyword names do not clash with another visible symbol.
285
286         \section kw_attributes Argument attribute values
287
288         The keywords are used to set argument attributes.  The keywords \ref default_value and \ref
289         parser influence, how an argument is parsed/interpreted whereas \ref name, \ref description,
290         \ref type_name and \ref default_doc are used to change the arguments documentation:
291         \code
292         void command(int);
293
294         dir.add("command", fty::Command(&command)
295             .arg( kw::name          = "name",
296                   kw::description   = "description",
297                   kw::default_value = 1,
298                   kw::type_name     = "type_name",
299                   kw::default_doc   = "default_doc" ) );
300         \endcode
301         Will create the following documentation:
302         \htmlonly
303         <pre>
304         Usage:
305             command [name:type_name]
306
307         With:
308             name      description
309                 default: default_doc
310         </pre>
311         \endhtmlonly
312
313         \see \ref senf::console::ParsedArgumentAttributor::arg()
314      */
315     namespace kw {
316         BOOST_PARAMETER_KEYWORD(type, name) ///< Argument name
317                                         /**< Sets the displayed name of the argument. */
318         BOOST_PARAMETER_KEYWORD(type, description) ///< One-line argument description
319                                         /**< This description is shown in the argument
320                                              reference. If several overloads have same-named
321                                              arguments, only one of them should be documented. This
322                                              documentation then applies to all arguments of that
323                                              name. */
324         BOOST_PARAMETER_KEYWORD(type, default_value) ///< Argument default value
325                                         /**< If a default value is specified for an argument, that
326                                              argument is optional. If an overload is called with
327                                              fewer arguments than defined, optional values will be
328                                              used beginning at the last optional argument and going
329                                              forward until all arguments have values assigned. E.g.,
330                                              an overload with 5 parameters \a a - \a e with two
331                                              defaults attached:
332                                              <pre>
333                                              command a:int [b:int] c:int [d:int] e:int
334                                              </pre>
335                                              When calling the overload, the arguments will be
336                                              assigned in the following way:
337                                              <table class="senf fixedwidth">
338                                              <tr>
339                                                <td style="whitespace:no-wrap"><tt>command 1 2</tt></td>
340                                                <td colspan="5">SyntaxErrorException: invalid number of
341                                                  arguments</td>
342                                              </tr>
343                                              <tr>
344                                                <td style="white-space:nowrap"><tt>command 1 2 3</tt></td>
345                                                <td style="width:6em">\a a = 1</td><td style="width:6em">\a b = \e default</td><td style="width:6em">\a c = 2</td><td style="width:6em">\a d = \e default</td><td style="width:6em">\a e = 3</td>
346                                              </tr>
347                                              <tr>
348                                                <td style="white-space:nowrap"><tt>command 1 2 3 4</tt></td>
349                                                <td>\a a = 1</td><td>\a b = 2</td><td>\a c = 3</td><td>\a d = \e default</td><td>\a e = 4</td>
350                                              </tr>
351                                              <tr>
352                                                <td style="white-space:nowrap"><tt>command 1 2 3 4 5</tt></td>
353                                                <td>\a a = 1</td><td>\a b = 2</td><td>\a c = 3</td><td>\a d = 4</td><td>\a e = 5</td>
354                                              </tr>
355                                              <tr>
356                                                <td style="white-space:nowrap"><tt>command 1 2 3 4 5 6</tt></td>
357                                                <td colspan="5">SyntaxErrorException: invalid number of
358                                                  arguments</td>
359                                              </tr>
360                                              </table>
361                                              So, if you use default values as you are used to,
362                                              assigning default values to consecutive trailing
363                                              arguments, they work like they do in C++ and most other
364                                              languages */
365         BOOST_PARAMETER_KEYWORD(type, type_name) ///< Type name of this arguments type
366                                         /**< By default, the type of an argument is extracted from
367                                              the C++ type name by taking the last component of the
368                                              fully scoped name. This value can be changed by setting
369                                              this attribute. */
370         BOOST_PARAMETER_KEYWORD(type, default_doc) ///< String rep of default value
371                                         /**< By default, the default value is documented by
372                                              converting the value to it's string representation
373                                              using the corresponding return value formatter which by
374                                              default uses \c boost::lexical_cast / \c iostreams. The
375                                              displayed value can be changed by setting this
376                                              attribute. */
377         BOOST_PARAMETER_KEYWORD(type, parser) ///< Argument parser
378                                         /**< The argument parser is used to convert the argument
379                                              token list returned by the console/config parser into
380                                              the appropriate value. If not set explicitly, this
381                                              conversion is supplied by the ArgumentTraits
382                                              class.
383
384                                              Setting the \a parser attribute allows to use a custom
385                                              parser. The parser is an arbitrary callable object with
386                                              the signature
387                                              \code
388                                              void parser(senf::console::ParseCommandInfo::TokensRange const & tokens, value_type & out);
389                                              \endcode
390                                              where \c value_type is the type of the overload
391                                              parameter. The parser must read and parse the complete
392                                              \a tokens range and return the parsed value in \a
393                                              out. If the parser fails, it must raise a
394                                              senf::console::SyntaxErrorException. */
395     }
396
397     /** \brief Derived class dependent ParsedCommandBase attributes
398
399         Attributes for parsed commands are not set directly on the node. They are set via a special
400         attributor temporary returned when adding a parsed command to the tree.
401
402         This class adds all those members, which do not depend on any specific argument but which
403         need to return the correct attributor type.
404
405         \see \ref console_autoparse
406      */
407     template <class Overload, class Self, class ReturnType=typename Overload::traits::result_type>
408     class ParsedArgumentAttributorBase
409         : public ParsedCommandAttributor<Overload>
410     {
411     public:
412         Self doc(std::string const & doc); ///< Set documentation for all overloads
413         Self shortdoc(std::string const & doc); ///< Set short documentation for all overloads
414         Self overloadDoc(std::string const & doc); ///< Set overload specific documentation
415         Self formatter(typename Overload::Formatter formatter);
416                                         ///< Set return value formatter
417                                         /**< This member is only available, if the \a ReturnType of
418                                              the installed callback is not \c void.
419
420                                              If \a ReturnType is not \c void, the \a formatter must
421                                              be a callable with a signature compatible with
422                                              \code
423                                              void formatter(ReturnType const & value, std::ostream & os);
424                                              \endcode
425                                              The \a formatter takes the return value of the call \a
426                                              value and writes it properly formated to \a os. */
427
428     protected:
429         ParsedArgumentAttributorBase(typename Overload::ptr overload, unsigned index);
430         ParsedArgumentAttributorBase(ParsedCommandAttributorBase const & other, unsigned index);
431
432     private:
433     };
434
435 #ifndef DOXYGEN
436
437     template <class Overload, class Self>
438     class ParsedArgumentAttributorBase<Overload, Self, void>
439         : public ParsedCommandAttributor<Overload>
440     {
441     public:
442         Self doc(std::string const & doc); ///< Set documentation for all overloads
443         Self shortdoc(std::string const & doc); ///< Set short documentation for all overloads
444         Self overloadDoc(std::string const & doc); ///< Set overload specific documentation
445
446     protected:
447         ParsedArgumentAttributorBase(typename Overload::ptr overload, unsigned index);
448         ParsedArgumentAttributorBase(ParsedCommandAttributorBase const & other, unsigned index);
449
450     private:
451     };
452
453 #endif
454
455     /** \brief Argument dependent ParsedCommandBase attributes
456
457         Attributes for parsed commands are not set directly on the node. They are set via a special
458         attributor temporary returned when adding a parsed command to the tree.
459
460         This class adds all those members, which depend on a specific argument. Each call to \c arg
461         will advance to the next argument.
462
463         \see \ref console_autoparse
464      */
465     template <class Overload, unsigned index, bool flag>
466     class ParsedArgumentAttributor
467         : public ParsedArgumentAttributorBase< Overload,
468                                                 ParsedArgumentAttributor<Overload, index, flag> >
469     {
470         typedef boost::parameter::parameters<
471             kw::type::name,
472             kw::type::description,
473             kw::type::default_value,
474             kw::type::type_name,
475             kw::type::default_doc,
476             kw::type::parser> arg_params;
477
478     public:
479         typedef typename senf::function_traits_arg_type<
480             typename Overload::traits, int(index) >::type arg_type;
481         typedef typename senf::remove_cvref< arg_type >::type value_type;
482         typedef ParsedArgumentAttributor<Overload, index+1> next_type;
483
484         next_type arg() const;          ///< Set argument attributes
485                                         /**< This member changes the attributes for the current
486                                              argument. The attributes are passed to arg() as keyword
487                                              arguments using the <a
488                                              href="http://www.boost.org/doc/libs/1_33_1/libs/parameter/doc/html/index.html">Boost.Parameter</a>
489                                              library.
490                                              \code
491                                              ...
492                                                  .arg( kw::name          = "name",
493                                                        kw::default_value = 1 )
494                                              ...
495                                              \endcode
496                                              The valid keywords are defined in the senf::console::kw
497                                              namespace.
498
499                                              Each call to arg() will increment the argument index
500                                              and advance to the next argument. This member is only
501                                              present, if there is an argument at the current
502                                              index. */
503
504 #ifndef DOXYVEN
505
506 #       define BOOST_PP_ITERATION_PARAMS_1                                                        \
507             (4, (1, BOOST_PARAMETER_MAX_ARITY,                                                    \
508                  SENF_ABSOLUTE_INCLUDE_PATH(Utils/Console/ParsedCommand.mpp),                     \
509                  5))
510 #       include BOOST_PP_ITERATE()
511
512 #endif
513
514     private:
515         explicit ParsedArgumentAttributor(typename Overload::ptr overload);
516         explicit ParsedArgumentAttributor(ParsedCommandAttributorBase const & other);
517
518         template <class ArgumentPack>
519         next_type argInfo(ArgumentPack const & args);
520         template <class Kw, class ArgumentPack>
521         void argInfo(Kw const &, ArgumentPack const &, boost::mpl::false_);
522
523         template <class ArgumentPack>
524         void argInfo(boost::parameter::keyword<kw::type::name> const &,
525                      ArgumentPack const & args, boost::mpl::true_);
526         template <class ArgumentPack>
527         void argInfo(boost::parameter::keyword<kw::type::description> const &,
528                      ArgumentPack const & args, boost::mpl::true_);
529         template <class ArgumentPack>
530         void argInfo(boost::parameter::keyword<kw::type::default_value> const &,
531                      ArgumentPack const & args, boost::mpl::true_);
532         template <class ArgumentPack>
533         void argInfo(boost::parameter::keyword<kw::type::type_name> const &,
534                      ArgumentPack const & args, boost::mpl::true_);
535         template <class ArgumentPack>
536         void argInfo(boost::parameter::keyword<kw::type::default_doc> const &,
537                      ArgumentPack const & args, boost::mpl::true_);
538         template <class ArgumentPack>
539         void argInfo(boost::parameter::keyword<kw::type::parser> const &,
540                      ArgumentPack const & args, boost::mpl::true_);
541
542         next_type next() const;
543
544         void defaultValue(value_type const & value);
545         template <class Fn> void parser(Fn fn);
546
547         template <class O, unsigned i, bool f>
548         friend class ParsedArgumentAttributor;
549
550         friend class detail::ParsedCommandAddNodeAccess;
551     };
552
553 #ifndef DOXYGEN
554
555     template <class Overload, unsigned index>
556     class ParsedArgumentAttributor<Overload, index, false>
557         : public ParsedArgumentAttributorBase< Overload,
558                                                 ParsedArgumentAttributor<Overload, index, false> >
559     {
560     public:
561         typedef OverloadedCommandNode node_type;
562         typedef ParsedArgumentAttributor return_type;
563
564     private:
565         explicit ParsedArgumentAttributor(typename Overload::ptr overload);
566         explicit ParsedArgumentAttributor(ParsedCommandAttributorBase const & other);
567
568         template <class O, unsigned i, bool f>
569         friend class ParsedArgumentAttributor;
570
571         friend class detail::ParsedCommandAddNodeAccess;
572     };
573
574 #endif
575
576 namespace factory {
577
578 #ifdef DOXYGEN
579
580     /** \brief OverloadedCommandNode factory
581
582         This factory will create new OverloadedCommandNode instances <em>or add new overloads</em>
583         to an existing OverloadedCommandNode. The factory supports automatic argument parsing.
584
585         Commands are added to the tree using
586         \code
587         namespace fty = senf::console::factory;
588         node.add("name", fty::Command(function));
589         \endcode
590
591         The Command factory supports the following features:
592         \li Automatic argument parsing
593         \li Automatic binding of member functions. Pass the owning instance as second argument to
594             the factory
595         \li Conversion to a compatible signature. Pass the signature as template argument to the
596             factory
597
598         If the signature of the command added matches
599         \code
600         void (std::ostream &, senf::console::ParsedCommandInfo const &)
601         \endcode
602         The command is added using manual argument parsing, otherwise it is added using automatic
603         argument parsing.
604
605         See the <a href="classsenf_1_1console_1_1factory_1_1Command-members.html">List of all
606         members</a> for additional attributes.
607
608         \note This class is for exposition only, the real interface consists of several overloaded
609             factory functions.
610
611         \see \ref console_manualparse \n
612             \ref console_autoparse
613      */
614     class Command : public ParsedArgumentAttributor
615     {
616     public:
617         typedef OverloadedCommandNode node_type;
618         typedef unspecified result_type;
619
620         Command(unspecified fn);        ///< Create a node calling \a fn
621         template <class Signature>
622         Command(unspecified fn);        ///< Create a node calling \a fn with signature \a Signature
623                                         /**< The given \a Signature must be compatible with \a fn
624                                              for each argument and the return value. */
625
626         Command(member_function_pointer fn, Owner const * owner);
627                                         ///< Create a node calling member function \a fn on \a owner
628         template <class Signature>
629         Command(member_function_pointer fn, Owner const * owner);
630                                         ///< Create a node calling member function \a fn on \a owner
631                                         ///  with the given \a Signature
632                                         /**< The given \a Signature must be compatible with \a fn
633                                              for each argument and the return value. */
634
635     };
636
637 #else
638
639     template <class Signature>
640     SimpleOverloadAttributor
641     Command(boost::function<Signature> fn,
642             typename boost::enable_if_c<detail::ParsedCommandTraits<Signature>::is_simple>::type * = 0);
643
644     template <class Function>
645     SimpleOverloadAttributor
646     Command(Function fn,
647             typename boost::enable_if_c<detail::ParsedCommandTraits<Function>::is_simple>::type * = 0);
648
649     template <class Owner, class Member>
650     SimpleOverloadAttributor
651     Command(Member memfn, Owner * owner,
652             typename boost::enable_if<boost::is_member_function_pointer<Member> >::type * = 0,
653             typename boost::enable_if_c<detail::ParsedCommandTraits<Member>::is_simple>::type * = 0);
654
655     template <class Owner, class Member>
656     SimpleOverloadAttributor
657     Command(Member memfn, Owner const * owner,
658             typename boost::enable_if<boost::is_member_function_pointer<Member> >::type * = 0,
659             typename boost::enable_if_c<detail::ParsedCommandTraits<Member>::is_simple>::type * = 0);
660
661     template <class CastTo, class Signature>
662     typename senf::console::detail::ParsedCommandTraits<CastTo>::Attributor
663     Command(boost::function<Signature> fn);
664
665     template <class CastTo, class Function>
666     typename senf::console::detail::ParsedCommandTraits<CastTo>::Attributor
667     Command(Function fn,
668             typename boost::enable_if_c<detail::ParsedCommandTraits<Function>::is_callable>::type * = 0,
669             typename boost::disable_if<boost::is_member_function_pointer<Function> >::type * = 0);
670
671     template <class Signature>
672     typename senf::console::detail::ParsedCommandTraits<Signature>::Attributor
673     Command(boost::function<Signature> fn);
674
675     template <class Function>
676     typename senf::console::detail::ParsedCommandTraits<Function>::Attributor
677     Command(Function fn,
678             typename boost::enable_if_c<detail::ParsedCommandTraits<Function>::is_callable>::type * = 0,
679             typename boost::disable_if<boost::is_member_function_pointer<Function> >::type * = 0);
680
681     template <class Owner, class Member>
682     typename senf::console::detail::ParsedCommandTraits<Member>::Attributor
683     Command(Member memfn, Owner * owner,
684             typename boost::enable_if<boost::is_member_function_pointer<Member> >::type * = 0);
685
686     template <class Owner, class Member>
687     typename senf::console::detail::ParsedCommandTraits<Member>::Attributor
688     Command(Member memfn, Owner const * owner,
689             typename boost::enable_if<boost::is_member_function_pointer<Member> >::type * = 0);
690
691     template <class CastTo, class Owner, class Member>
692     typename senf::console::detail::ParsedCommandTraits<CastTo>::Attributor
693     Command(Member memfn, Owner * owner,
694             typename boost::enable_if<boost::is_member_function_pointer<Member> >::type * = 0);
695
696     template <class CastTo, class Owner, class Member>
697     typename senf::console::detail::ParsedCommandTraits<CastTo>::Attributor
698     Command(Member memfn, Owner const * owner,
699             typename boost::enable_if<boost::is_member_function_pointer<Member> >::type * = 0);
700
701 #endif
702
703 }}}
704
705 ///////////////////////////////hh.e////////////////////////////////////////
706 #include "ParsedCommand.cci"
707 #include "ParsedCommand.ct"
708 #include "ParsedCommand.cti"
709 #endif
710
711 \f
712 // Local Variables:
713 // mode: c++
714 // fill-column: 100
715 // comment-column: 40
716 // c-file-style: "senf"
717 // indent-tabs-mode: nil
718 // ispell-local-dictionary: "american"
719 // compile-command: "scons -u test"
720 // End: