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