Console: Implement keyword arguments for 'arg'
g0dil [Wed, 9 Apr 2008 23:52:51 +0000 (23:52 +0000)]
git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@798 270642c3-0616-0410-b53a-bc976706d245

Console/ParsedCommand.cti
Console/ParsedCommand.hh
Console/ParsedCommand.mpp
Console/ParsedCommand.test.cc

index 6809191..72f372e 100644 (file)
@@ -28,6 +28,7 @@
 // Custom includes
 #include "../Utils/membind.hh"
 #include <boost/format.hpp>
+#include <boost/parameter/binding.hpp>
 
 #define prefix_ inline
 ///////////////////////////////cti.p///////////////////////////////////////
@@ -117,9 +118,45 @@ ParsedAttributeAttributorBase(Overload & overload, unsigned index)
 // senf::console::ParsedAttributeAttributor<Overload,index,flag>
 
 template <class Overload, unsigned index, bool flag>
-prefix_ senf::console::ParsedAttributeAttributor<Overload, index+1>
-senf::console::ParsedAttributeAttributor<Overload,index,flag>::arg(std::string const & name,
-                                                                   std::string const & doc)
+template <class ArgumentPack>
+prefix_ typename senf::console::ParsedAttributeAttributor<Overload,index,flag>::next_type
+senf::console::ParsedAttributeAttributor<Overload,index,flag>::
+argInfo(ArgumentPack const & args)
+    const
+{
+    typedef typename boost::parameter::binding<
+        ArgumentPack, tag::detail::default_value_>::type default_value_t;
+    return argInfo( args, boost::is_same<default_value_t, void>() );
+}
+
+template <class Overload, unsigned index, bool flag>
+template <class ArgumentPack>
+prefix_ typename senf::console::ParsedAttributeAttributor<Overload,index,flag>::next_type
+senf::console::ParsedAttributeAttributor<Overload,index,flag>::
+argInfo(ArgumentPack const & args, boost::mpl::true_)
+    const
+{
+    return argInfo( args[tag::name_ | ""], 
+                    args[tag::description_ | ""] );
+
+}
+
+template <class Overload, unsigned index, bool flag>
+template <class ArgumentPack>
+prefix_ typename senf::console::ParsedAttributeAttributor<Overload,index,flag>::next_type
+senf::console::ParsedAttributeAttributor<Overload,index,flag>::
+argInfo(ArgumentPack const & args, boost::mpl::false_)
+    const
+{
+    return argInfo( args[tag::name_ | ""], 
+                    args[tag::description_ | ""], 
+                    args[tag::default_value_ | value_type()] );
+}
+
+template <class Overload, unsigned index, bool flag>
+prefix_ typename senf::console::ParsedAttributeAttributor<Overload,index,flag>::next_type
+senf::console::ParsedAttributeAttributor<Overload,index,flag>::argInfo(std::string const & name,
+                                                                       std::string const & doc)
     const
 {
     this->argName(name);
@@ -128,10 +165,10 @@ senf::console::ParsedAttributeAttributor<Overload,index,flag>::arg(std::string c
 }
 
 template <class Overload, unsigned index, bool flag>
-prefix_ senf::console::ParsedAttributeAttributor<Overload, index+1>
-senf::console::ParsedAttributeAttributor<Overload,index,flag>::arg(std::string const & name,
-                                                                   std::string const & doc,
-                                                                   value_type const & value)
+prefix_ typename senf::console::ParsedAttributeAttributor<Overload,index,flag>::next_type
+senf::console::ParsedAttributeAttributor<Overload,index,flag>::argInfo(std::string const & name,
+                                                                       std::string const & doc,
+                                                                       value_type const & value)
     const
 {
     this->argName(name);
@@ -170,7 +207,7 @@ template <class Overload, unsigned index>
 prefix_
 senf::console::ParsedAttributeAttributor<Overload, index, false>::
 ParsedAttributeAttributor(Overload & overload)
-    : ParsedAttributeAttributorBase<Overload, ParsedAttributeAttributor> (overload, index)
+    : ParsedCommandAttributor<Overload> (overload, index)
 {}
 
 ///////////////////////////////////////////////////////////////////////////
index 020fe6f..14d63a0 100644 (file)
@@ -33,6 +33,8 @@
 #include <boost/type_traits/is_same.hpp>
 #include <boost/mpl/if.hpp>
 #include <boost/utility.hpp>
+#include <boost/parameter/keyword.hpp>
+#include <boost/parameter/parameters.hpp>
 #include "../config.hh"
 #include "OverloadedCommand.hh"
 #include "ParseParameter.hh"
@@ -115,6 +117,12 @@ namespace console {
 
     private:
     };
+    
+    namespace tag {
+        BOOST_PARAMETER_KEYWORD(detail, name_);
+        BOOST_PARAMETER_KEYWORD(detail, description_);
+        BOOST_PARAMETER_KEYWORD(detail, default_value_);
+    }
 
     template <class Overload, class Self>
     class ParsedAttributeAttributorBase
@@ -130,7 +138,9 @@ namespace console {
     private:
     };
 
-    template <class Overload, unsigned index=0, bool flag=(index < unsigned(Overload::traits::arity))>
+    template < class Overload, 
+               unsigned index=0, 
+               bool flag=(index < unsigned(Overload::traits::arity)) >
     class ParsedAttributeAttributor
         : public ParsedAttributeAttributorBase< Overload, 
                                                 ParsedAttributeAttributor<Overload, index, flag> >
@@ -139,19 +149,37 @@ namespace console {
         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<Overload, index+1> next_type;
 
         typedef OverloadedCommandNode node_type;
         typedef ParsedAttributeAttributor return_type;
 
-        ParsedAttributeAttributor<Overload, index+1> arg(std::string const & name = "",
-                                                         std::string const & doc = "") const;
-        ParsedAttributeAttributor<Overload, index+1> arg(std::string const & name,
-                                                         std::string const & doc,
-                                                         value_type const & value) const;
+        typedef boost::parameter::parameters<
+            tag::detail::name_,
+            tag::detail::description_,
+            tag::detail::default_value_> arg_params;
+
+        next_type arg() const;
+
+#       define BOOST_PP_ITERATION_PARAMS_1 \
+            (4, (1, 3, SENF_ABSOLUTE_INCLUDE_PATH(Console/ParsedCommand.mpp), 5))
+#       include BOOST_PP_ITERATE()
 
     private:
         explicit ParsedAttributeAttributor(Overload & overload);
 
+        template <class ArgumentPack>
+        next_type argInfo(ArgumentPack const & args) const;
+
+        template <class ArgumentPack>
+        next_type argInfo(ArgumentPack const & args, boost::mpl::true_) const;
+        template <class ArgumentPack>
+        next_type argInfo(ArgumentPack const & args, boost::mpl::false_) const;
+
+        next_type argInfo(std::string const & name, std::string const & doc) const;
+        next_type argInfo(std::string const & name, std::string const & doc,
+                          value_type const & value) const;
+
         ParsedAttributeAttributor<Overload, index+1> next() const;
 
         void defaultValue(value_type const & value) const;
@@ -169,13 +197,13 @@ namespace console {
             ParsedCommandOverload<typename detail::ParsedCommandTraits<Function>::traits> >
         senf_console_add_node(DirectoryNode & node, Owner & owner, std::string const & name,
                               Function fn, int,
-                              typename boost::enable_if_c<detail::ParsedCommandTraits<Function>::is_member>::type * = 0);
+                              typename boost::enable_if_c<
+                                  detail::ParsedCommandTraits<Function>::is_member>::type * = 0);
     };
 
     template <class Overload, unsigned index>
     class ParsedAttributeAttributor<Overload, index, false>
-        : public ParsedAttributeAttributorBase< Overload, 
-                                                ParsedAttributeAttributor<Overload, index, false> >
+        : public ParsedCommandAttributor< Overload >
     {
     public:
         typedef OverloadedCommandNode node_type;
@@ -197,7 +225,8 @@ namespace console {
             ParsedCommandOverload<typename detail::ParsedCommandTraits<Function>::traits> >
         senf_console_add_node(DirectoryNode & node, Owner & owner, std::string const & name,
                               Function fn, int,
-                              typename boost::enable_if_c<detail::ParsedCommandTraits<Function>::is_member>::type * = 0);
+                              typename boost::enable_if_c<
+                                  detail::ParsedCommandTraits<Function>::is_member>::type * = 0);
     };
 
 #ifndef DOXYGEN
@@ -212,7 +241,8 @@ namespace console {
         ParsedCommandOverload<typename detail::ParsedCommandTraits<Function>::traits> >
     senf_console_add_node(DirectoryNode & node, Owner & owner, std::string const & name,
                           Function fn, int,
-                          typename boost::enable_if_c<detail::ParsedCommandTraits<Function>::is_member>::type * = 0);
+                          typename boost::enable_if_c<
+                              detail::ParsedCommandTraits<Function>::is_member>::type * = 0);
 
 #endif
 
index b2830ea..df42e0a 100644 (file)
@@ -29,6 +29,8 @@
 // Custom includes
 #include <boost/preprocessor/iteration/iterate.hpp>
 #include <boost/preprocessor/repetition/enum_trailing.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
 #include <boost/preprocessor/cat.hpp>
 #include <boost/preprocessor/arithmetic/inc.hpp>
 #include <boost/preprocessor/repetition/repeat.hpp>
@@ -167,6 +169,19 @@ struct CreateParsedCommandOverload<Traits, true, BOOST_PP_ITERATION()>
 };
 
 // ////////////////////////////////////////////////////////////////////////
+#elif BOOST_PP_ITERATION_FLAGS()==5 // ////////////////////////////////////
+// ////////////////////////////////////////////////////////////////////////
+
+// Create keyword arg forwarding functions
+
+template <BOOST_PP_ENUM_PARAMS( BOOST_PP_ITERATION(), class A ) > 
+next_type arg ( BOOST_PP_ENUM_BINARY_PARAMS( BOOST_PP_ITERATION(), A, const & a ),
+                typename arg_params::match< BOOST_PP_ENUM_PARAMS( BOOST_PP_ITERATION(), A ) >::type
+                    kw = arg_params()) const {
+    return argInfo( kw(BOOST_PP_ENUM_PARAMS( BOOST_PP_ITERATION(), a )) );
+}
+
+// ////////////////////////////////////////////////////////////////////////
 #endif // /////////////////////////////////////////////////////////////////
 // ////////////////////////////////////////////////////////////////////////
 // Undefine local Macros
index b7c78d6..94ab8fa 100644 (file)
@@ -118,25 +118,33 @@ BOOST_AUTO_UNIT_TEST(parsedCommand)
     {
         std::stringstream ss;
 
-        senf::console::OverloadedCommandNode & cbNode ( dir.add("cb", &cb1)
+        using namespace senf::console::tag;
+
+        dir.add("cb", &cb1)
             .doc(
                 "Ops fortunate, ops me ut orgia vociferatio contumax per, rudo re loco emitto\n"
                 "intolerabiliter ita iugo. Subcribo gravo. Devenio luna fonticulus Castanea\n"
                 "horum fascino Os interpretor non ipse conjuratio hora, qui filius denuntio ait\n"
                 "sono te odium Anhelo. Dum Cedo audax celox alius una Agnosco hic, ibi retineo\n"
                 "lux sto ioco. Per Re dono. Copiose reus scitus jus diligens sis scapulare\n"
-                "Servitium transi.")
+                "Servitium transi." )
+
             .overloadDoc(
                 "Lo nam balnearius Opprimo Pennatus, no decentia sui, dicto esse se pulchritudo,\n"
-                "pupa Sive res indifferenter. Captivo pa.")
-            .arg("", "Bar didelfrump di desgorb. Nu widsoflar brimeldrgf.")
-            .arg("checkup", "Florgel, dargel and durgel", 2.1) );
+                "pupa Sive res indifferenter. Captivo pa." )
 
-        dir.add("cb", &cb5)
-            .overloadDoc(
-                "Uus Primordia fundo falsidicus corium, diurnitas humo pro leto. Sui Ueraciter\n"
-                "hio eruca lenis qua Agalmate ut fors penitentia. Iugum obdormio anxio nuncupo\n"
-                "iam, in vos nam Custodi.");
+            .arg( description_   = "Bar didelfrump di desgorb. Nu widsoflar brimeldrgf." )
+
+            .arg( name_          = "checkup", 
+                  description_   = "Florgel, dargel and durgel",
+                  default_value_ = 2.1 );
+
+        senf::console::OverloadedCommandNode & cbNode (
+            dir.add("cb", &cb5)
+                .overloadDoc(
+                    "Uus Primordia fundo falsidicus corium, diurnitas humo pro leto. Sui Ueraciter\n"
+                    "hio eruca lenis qua Agalmate ut fors penitentia. Iugum obdormio anxio nuncupo\n"
+                    "iam, in vos nam Custodi." ) );
 
         (void) cbNode;