Whitespce cleanup: Remove whitespace at end-on-line, remove tabs, wrap
[senf.git] / senf / Utils / Console / Node.hh
index 3158023..5765dd6 100644 (file)
 
         SomeClass() : dir(this)
         {
+            namespace fty = senf::console::factory;
             // You may document the directory here or later when adding it to the tree
             dir.doc("Manager for something");
 
             // Add a member function (the pointer-to-member is automatically bound to this instance)
-            dir.add("member", &SomeClass::member)
-                .doc("Do the member operation");
+            dir.add("member", fty::Command(this, &SomeClass::member)
+                .doc("Do the member operation"));
         }
 
         void member(std::ostream & os, senf::console::ParseCommandInfo const & command)
@@ -69,6 +70,8 @@
 
     int main(int, char**)
     {
+        namespace fty = senf::console::factory;
+
         // Provide global documentation
         senf::console::root()
             .doc("This is someServer server");
         // Add a new directory to the root and document it. All the mutators return the node object
         // itself so operations can be chained.
         senf::console::DirectoryNode & mydir ( senf::console::root()
-                .mkdir("myserver")
-                .doc("My server specific directory"));
+                .add("myserver", fty::Directory()
+                     .doc("My server specific directory")));
 
         // Add a command to that directory
-        mydir.add("mycommand", &mycommand)
+        mydir.add("mycommand", fty::Command(&mycommand)
             .doc("mycommand <foo> [<bar>]\n\n"
-                 "If <bar> is given, flurgle the <foo>, otherwise burgle it");
+                 "If <bar> is given, flurgle the <foo>, otherwise burgle it"));
 
         // Create a SomeClass instance and add it's directory.
         SomeClass someClass;
 #include <boost/enable_shared_from_this.hpp>
 #include <boost/utility.hpp>
 #include <boost/range/iterator_range.hpp>
-#include <boost/typeof/typeof.hpp>
-#include <boost/type_traits/remove_reference.hpp>
 #include <boost/any.hpp>
 #include <senf/Utils/Exception.hh>
-#include <senf/Utils/mpl.hh>
 #include <senf/Utils/Logger/SenfLog.hh>
-#include <senf/Utils/type_traits.hh>
-#include "Parse.hh"
 
 //#include "Node.mpp"
 ///////////////////////////////hh.p////////////////////////////////////////
@@ -223,6 +221,8 @@ namespace console {
     class DirectoryNode;
     class CommandNode;
 
+    namespace detail { struct NodeFactory {}; }
+
     /** \brief Get console root node */
     DirectoryNode & root();
 
@@ -230,7 +230,7 @@ namespace console {
 
         Recursively dumps the console directory structure starting at \a dir. By default, dumps the
         complete tree beginning at the root node.
-        
+
         In contrast to the console 'lr' command, links are dumped by showing the \e absolute path
         to the target node.
      */
@@ -382,31 +382,6 @@ namespace console {
 
     class SimpleCommandNode;
 
-    /** \brief Internal: Node creation helper traits
-
-        This class is used internally to find out the type of node to create for a specific argument
-        type.
-     */
-    template <class Object>
-    struct NodeCreateTraits
-    {
-        typedef BOOST_TYPEOF_TPL( senf_console_add_node(
-                                      * static_cast<DirectoryNode *>(0),
-                                      * static_cast<std::string const *>(0),
-                                      * static_cast<Object *>(0),
-                                      0) ) base_type;
-        typedef typename senf::remove_cvref<base_type>::type value_type;
-
-        typedef typename value_type::node_type NodeType;
-        typedef typename value_type::return_type result_type;
-
-        /// Internal
-        struct Creator {
-            static result_type create(DirectoryNode & node, std::string const & name,
-                                      Object & ob);
-        };
-    };
-
     /** \brief Config/console tree directory node
 
         This node type provides the internal and root nodes of the tree. It allows to add arbitrary
@@ -469,38 +444,17 @@ namespace console {
                                              '-n' is added to the name until the name is unique. If
                                              \a name is empty, it is set to 'unnamed'. */
 
-        template <class Object>
-        typename NodeCreateTraits<Object>::result_type add(std::string const & name,
-                                                           Object const & ob);
+        template <class NodeType>
+        NodeType & add(std::string const & name, NodeType & node,
+                       typename boost::enable_if< boost::is_convertible<NodeType &, GenericNode &> >::type * = 0);
+
+        template <class Factory>
+        typename Factory::result_type add(std::string const & name, Factory const & factory,
+                                          typename boost::enable_if< boost::is_convertible<Factory const &, detail::NodeFactory const &> >::type * = 0);
                                         ///< Generic child node factory
                                         /**< This member is used to create a new child node of the
                                              current directory. The type of node created depends on
-                                             the type of argument passed.
-
-                                             The node type is selected by the NodeCreateTraits
-                                             class. To allow adding a specific node type, you need
-                                             to provide an overload for
-                                             <tt>senf_console_add_node</tt> which must be visible at
-                                             when you register the new node.
-                                             \code
-                                             MyNodeType & senf_console_add_node(
-                                                 DirectoryNode & dir,
-                                                 std::string const & name,
-                                                 MySpecialObject const & ob,
-                                                 int)
-                                             {
-                                                 return dir.add(name, MyNodeType::create(ob));
-                                             }
-                                             \endcode
-                                             (Do not forget the last unnamed 'int' parameter which
-                                             is not used but serves to disambiguate the
-                                             overloads). */
-
-        template <class Object>
-        typename NodeCreateTraits<Object>::result_type add(std::string const & name,
-                                                           Object & ob);
-                                        ///< Generic child node factory
-                                        /**< \see add() */
+                                             the type of argument passed. */
 
         GenericNode::ptr remove(std::string const & name);
                                         ///< Remove node \a name from the tree
@@ -553,11 +507,6 @@ namespace console {
                                              \throws std::bad_cast if the child \a name is not a
                                                  command node. */
 
-        DirectoryNode & mkdir(std::string const & name);
-                                        ///< Create sub-directory node
-        DirectoryNode & provideDirectory(std::string const & name);
-                                        ///< Return subdirectory, possibly creating it
-
         ChildrenRange children() const; ///< Return iterator range over all children.
                                         /**< The returned range is sorted by child name. */
 
@@ -565,10 +514,6 @@ namespace console {
                                         ///< Return iterator range of completions for \a s
                                         /**< The returned range is sorted by child name. */
 
-        void link(std::string const & name, GenericNode & target);
-                                        ///< Create a child node which is a link to target. \a s
-                                        /**< The new link node will be a child of the node for which this member function is called. */
-
         ///\}
         ///////////////////////////////////////////////////////////////////////////
 
@@ -597,12 +542,6 @@ namespace console {
     struct UnknownNodeNameException : public senf::Exception
     { UnknownNodeNameException() : senf::Exception("Unknown node name") {}};
 
-#ifndef DOXYGEN
-    template <class Type>
-    struct NodeCreateTraits< boost::shared_ptr<Type> >
-    {};
-#endif
-
     /** \brief Config/console tree command node
 
         The CommandNode is the base-class for the tree leaf nodes. Concrete command node
@@ -635,7 +574,7 @@ namespace console {
                                              \param[in] command command arguments. This is a
                                                  range of ranges of Token instances. */
 
-        void execute(boost::any & rv, std::ostream & output, ParseCommandInfo const & command) 
+        void execute(boost::any & rv, std::ostream & output, ParseCommandInfo const & command)
             const;
                                         ///< Execute the command
                                         /**< \param[out] rv command return value
@@ -733,23 +672,68 @@ namespace console {
         std::string shortdoc_;
     };
 
+    DirectoryNode & provideDirectory(DirectoryNode & dir, std::string const & name);
+
 #ifndef DOXYGEN
 
-    SimpleCommandNode & senf_console_add_node(DirectoryNode & node, std::string const & name,
-                                              SimpleCommandNode::Function fn, int);
+namespace factory {
 
-    DirectoryNode & senf_console_add_node(DirectoryNode & node, std::string const & name,
-                                          DirectoryNode & dir, int);
+    class SimpleCommand
+        : public detail::NodeFactory
+    {
+    public:
+        typedef SimpleCommandNode node_type;
+        typedef SimpleCommandNode & result_type;
 
-#endif
+        explicit SimpleCommand(SimpleCommandNode::Function fn);
 
-}}
+        SimpleCommandNode & create(DirectoryNode & dir, std::string const & name) const;
+
+        SimpleCommand const & doc(std::string const & doc) const;
+        SimpleCommand const & shortdoc(std::string const & doc) const;
 
-#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
+    private:
+        SimpleCommandNode::ptr node_;
+    };
+
+    class Directory
+        : public detail::NodeFactory
+    {
+    public:
+        typedef DirectoryNode node_type;
+        typedef DirectoryNode & result_type;
 
-BOOST_TYPEOF_REGISTER_TYPE(senf::console::DirectoryNode)
-BOOST_TYPEOF_REGISTER_TYPE(senf::console::SimpleCommandNode)
+        Directory();
 
+        DirectoryNode & create(DirectoryNode & dir, std::string const & name) const;
+
+        Directory const & doc(std::string const & doc) const;
+        Directory const & shortdoc(std::string const & doc) const;
+
+    private:
+        DirectoryNode::ptr node_;
+    };
+
+    class Link
+        : public detail::NodeFactory
+    {
+    public:
+        typedef LinkNode node_type;
+        typedef LinkNode & result_type;
+
+        explicit Link(GenericNode & target);
+
+        LinkNode & create(DirectoryNode & dir, std::string const & name) const;
+
+    private:
+        LinkNode::ptr node_;
+    };
+
+}
+
+#endif
+
+}}
 
 ///////////////////////////////hh.e////////////////////////////////////////
 #include "Node.cci"