X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Console%2FParsedCommand.hh;h=9f43d157be19f8ba6bb68d5f49db700849a021ce;hb=63c40810b93b4d8f3d6dad5f987adc5f2bf5b5ed;hp=7df4366b4b98118f64a8dce0b1ae215e424ce007;hpb=da7b4fef4655148b8cfb2857e0d80e4d92a3b65e;p=senf.git diff --git a/Console/ParsedCommand.hh b/Console/ParsedCommand.hh index 7df4366..9f43d15 100644 --- a/Console/ParsedCommand.hh +++ b/Console/ParsedCommand.hh @@ -37,7 +37,7 @@ #include #include "../config.hh" #include "OverloadedCommand.hh" -#include "ParseParameter.hh" +#include "Traits.hh" #include "../Utils/type_traits.hh" #include "ParsedCommand.ih" @@ -47,6 +47,8 @@ namespace senf { namespace console { + namespace detail { class ArgumentInfoBase; } + /** \brief CommandOverload implementation with automatic argument parsing ParsedCommandOverloadBase implements a CommandOverload implementation supporting automatic @@ -69,7 +71,7 @@ namespace console { \endcode There are quite a number of additional parameters available to be set. These parameters are - documented in ParsedAttributeAttributor. Parameters are set by adding them as additional + documented in ParsedArgumentAttributor. Parameters are set by adding them as additional calls after adding the node: \code @@ -115,13 +117,13 @@ namespace console { used as argument type. However, argument parsing can be configured by specializing - senf::console::detail::ParameterTraits. See that class for more information. + senf::console::ArgumentTraits. See that class for more information. \section overload_format Custom return-value formatters By default, return values are streamed to an ostream. This automatically allows any streamable type to be used as return value. To add new types or customize the formating, the - senf::console::detail::ReturnValueTraits template needs to be specialized for that type. See + senf::console::ReturnValueTraits template needs to be specialized for that type. See that class for more information. \ingroup console_commands @@ -132,8 +134,8 @@ namespace console { public: typedef boost::intrusive_ptr ptr; - detail::ParameterInfoBase & arg(unsigned n) const; - template detail::ParameterInfo & arg(unsigned n) const; + detail::ArgumentInfoBase & arg(unsigned n) const; + template detail::ArgumentInfo & arg(unsigned n) const; void doc(std::string const & d); @@ -148,24 +150,56 @@ namespace console { virtual void v_argumentDoc(unsigned index, ArgumentDoc & doc) const; virtual std::string v_doc() const; - typedef std::vector Parameters; + typedef std::vector Parameters; Parameters parameters_; std::string doc_; }; + /** \brief Parsed command overload + + ParsedCommandOverload provides the command overload added to an OverloadedCommandNode for an + automatically parsed command. + + This class is normally instantiated automatically when adding a function or member-function + pointer as callback to the tree. Manually instantiation this type of overload is \e not + simple, since the function signature has to be manipulated correctly to support the optional + \c std::ostream first argument. + + \implementation This class is specialized for each supported number of command arguments. + */ template - class ParsedCommandOverload {}; + class ParsedCommandOverload : public ParsedCommandOverloadBase + { + public: + typedef boost::intrusive_ptr ptr; + +#ifdef DOXYGEN + static ptr create(Function fn); +#endif + }; + +#ifndef DOXYGEN # define BOOST_PP_ITERATION_PARAMS_1 (4, (0, SENF_CONSOLE_MAX_COMMAND_ARITY, \ SENF_ABSOLUTE_INCLUDE_PATH(Console/ParsedCommand.mpp), \ 1)) # include BOOST_PP_ITERATE() +#endif + + /** \brief Generic ParsedCommandOverladBase attributes + + Attributes for parsed commands are not set directly on the node. They are set via a special + attributor temporary returned when adding a parsed command to the tree. + + This class is the base class for those attributors. It provides members which do not depend + in any way on the exact type of command added. + */ class ParsedCommandAttributorBase { public: - OverloadedCommandNode & node() const; - operator OverloadedCommandNode & () const; + OverloadedCommandNode & node() const; ///< Return the node object + operator OverloadedCommandNode & () const; ///< Automatically convert to node object protected: ParsedCommandAttributorBase(ParsedCommandOverloadBase & overload, unsigned index); @@ -184,75 +218,133 @@ namespace console { unsigned index_; }; + /** \brief Non argument dependent ParsedCommandBase attributes + + Attributes for parsed commands are not set directly on the node. They are set via a special + attributor temporary returned when adding a parsed command to the tree. + + This class adds all those members, which do depend on the type of command added (and thereby + on that commands signature) but do not depend on the type of any single argument. + + \fixme Implement compile-time checking, that after a defaulted arg only defaulted args are + allowed. + */ template class ParsedCommandAttributor : public ParsedCommandAttributorBase { public: - Overload & overload() const; + Overload & overload() const; ///< Get the command overload protected: ParsedCommandAttributor(Overload & overload, unsigned index); private: }; - + + /** \brief Keyword argument tags + + The tags defined in this namespace are used as keyword arguments via the Boost.Parameter + library. + + For the keyword tags, the standard C++ scoping rules apply: + \li Either qualify them with their complete namespace: arg( senf::console::kw::name = + "name" ) + \li or use a namespace alias: namespace kw = senf::console::kw; arg( kw::name = "name" + ); + \li import the keywords into your namespace: using namespace senf::console::kw; arg( + name = "name"); + + The second alternative is preferred, the using namespace directive may be used as + long as the keyword names do not clash with another visible symbol. + */ namespace kw { - BOOST_PARAMETER_KEYWORD(type, name); - BOOST_PARAMETER_KEYWORD(type, description); - BOOST_PARAMETER_KEYWORD(type, default_value); + BOOST_PARAMETER_KEYWORD(type, name) ///< Argument name + BOOST_PARAMETER_KEYWORD(type, description) ///< One-line Argument description + BOOST_PARAMETER_KEYWORD(type, default_value) ///< Argument default value } + /** \brief Derived class dependent ParsedCommandBase attributes + + Attributes for parsed commands are not set directly on the node. They are set via a special + attributor temporary returned when adding a parsed command to the tree. + + This class adds all those members, which do not depend on any specific argument but which + need to return the correct attributor type. + */ template - class ParsedAttributeAttributorBase + class ParsedArgumentAttributorBase : public ParsedCommandAttributor { public: - Self doc(std::string const & doc) const; - Self overloadDoc(std::string const & doc) const; + Self doc(std::string const & doc) const; ///< Set documentation for all overloads + Self overloadDoc(std::string const & doc) const; ///< Set overload specific documentation protected: - ParsedAttributeAttributorBase(Overload & overload, unsigned index); + ParsedArgumentAttributorBase(Overload & overload, unsigned index); private: }; + + /** \brief Argument dependent ParsedCommandBase attributes + + Attributes for parsed commands are not set directly on the node. They are set via a special + attributor temporary returned when adding a parsed command to the tree. + + This class adds all those members, which depend on a specific argument. Each call to \c arg + will advance to the next argument. + */ template < class Overload, unsigned index=0, bool flag=(index < unsigned(Overload::traits::arity)) > - class ParsedAttributeAttributor - : public ParsedAttributeAttributorBase< Overload, - ParsedAttributeAttributor > + class ParsedArgumentAttributor + : public ParsedArgumentAttributorBase< Overload, + ParsedArgumentAttributor > { + typedef boost::parameter::parameters< + kw::type::name, + kw::type::description, + kw::type::default_value> arg_params; + public: + typedef OverloadedCommandNode node_type; + typedef ParsedArgumentAttributor return_type; + typedef typename senf::function_traits_arg_type< typename Overload::traits, int(index) >::type arg_type; typedef typename senf::remove_cvref< arg_type >::type value_type; - typedef ParsedAttributeAttributor next_type; + typedef ParsedArgumentAttributor next_type; - typedef OverloadedCommandNode node_type; - typedef ParsedAttributeAttributor return_type; + next_type arg() const; ///< Set argument attributes + /**< This member changes the attributes for the current + argument. The attributes are passed to arg() as keyword + arguments using the Boost.Parameter + library. The valid keywords are defined in the + senf::console::kw namespace. - typedef boost::parameter::parameters< - kw::type::name, - kw::type::description, - kw::type::default_value> arg_params; + This member is only present, if there is an argument at + the current index. */ - next_type arg() const; +#ifndef DOXYVEN # define BOOST_PP_ITERATION_PARAMS_1 \ (4, (1, 3, SENF_ABSOLUTE_INCLUDE_PATH(Console/ParsedCommand.mpp), 5)) # include BOOST_PP_ITERATE() +#endif + private: - explicit ParsedAttributeAttributor(Overload & overload); + explicit ParsedArgumentAttributor(Overload & overload); template next_type argInfo(ArgumentPack const & args) const; - template void argInfo(Kw const &, ArgumentPack const &, boost::mpl::true_) const; + template void argInfo(boost::parameter::keyword const &, ArgumentPack const & args, boost::mpl::false_) @@ -271,44 +363,50 @@ namespace console { void defaultValue(value_type const & value) const; template - friend class ParsedAttributeAttributor; + friend class ParsedArgumentAttributor; + +#ifndef DOXYGEN template - friend ParsedAttributeAttributor< + friend ParsedArgumentAttributor< ParsedCommandOverload::traits> > senf_console_add_node(DirectoryNode & node, std::string const & name, Function fn, int); template - friend ParsedAttributeAttributor< + friend ParsedArgumentAttributor< ParsedCommandOverload::traits> > senf_console_add_node(DirectoryNode & node, Owner & owner, std::string const & name, Function fn, int, typename boost::enable_if_c< detail::ParsedCommandTraits::is_member>::type * = 0); + +#endif }; +#ifndef DOXYGEN + template - class ParsedAttributeAttributor - : public ParsedAttributeAttributorBase< Overload, - ParsedAttributeAttributor > + class ParsedArgumentAttributor + : public ParsedArgumentAttributorBase< Overload, + ParsedArgumentAttributor > { public: typedef OverloadedCommandNode node_type; - typedef ParsedAttributeAttributor return_type; + typedef ParsedArgumentAttributor return_type; private: - explicit ParsedAttributeAttributor(Overload & overload); + explicit ParsedArgumentAttributor(Overload & overload); template - friend class ParsedAttributeAttributor; + friend class ParsedArgumentAttributor; template - friend ParsedAttributeAttributor< + friend ParsedArgumentAttributor< ParsedCommandOverload::traits> > senf_console_add_node(DirectoryNode & node, std::string const & name, Function fn, int); template - friend ParsedAttributeAttributor< + friend ParsedArgumentAttributor< ParsedCommandOverload::traits> > senf_console_add_node(DirectoryNode & node, Owner & owner, std::string const & name, Function fn, int, @@ -316,15 +414,13 @@ namespace console { detail::ParsedCommandTraits::is_member>::type * = 0); }; -#ifndef DOXYGEN - template - ParsedAttributeAttributor< + ParsedArgumentAttributor< ParsedCommandOverload::traits> > senf_console_add_node(DirectoryNode & node, std::string const & name, Function fn, int); template - ParsedAttributeAttributor< + ParsedArgumentAttributor< ParsedCommandOverload::traits> > senf_console_add_node(DirectoryNode & node, Owner & owner, std::string const & name, Function fn, int, @@ -338,7 +434,7 @@ namespace console { #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() BOOST_TYPEOF_REGISTER_TEMPLATE(senf::console::ParsedCommandOverload, (class,unsigned)) -BOOST_TYPEOF_REGISTER_TEMPLATE(senf::console::ParsedAttributeAttributor, (class, unsigned, bool)) +BOOST_TYPEOF_REGISTER_TEMPLATE(senf::console::ParsedArgumentAttributor, (class, unsigned, bool)) BOOST_TYPEOF_REGISTER_TEMPLATE(boost::function_traits, 1) ///////////////////////////////hh.e////////////////////////////////////////