Fix documentation build under maverick (doxygen 1.7.1)
[senf.git] / senf / Utils / Console / Variables.hh
index 4f93a93..a2cf855 100644 (file)
@@ -1,6 +1,6 @@
 // $Id$
 //
-// Copyright (C) 2008 
+// Copyright (C) 2008
 // Fraunhofer Institute for Open Communication Systems (FOKUS)
 // Competence Center NETwork research (NET), St. Augustin, GERMANY
 //     Stefan Bund <g0dil@berlios.de>
 #include <boost/utility.hpp>
 #include <boost/type_traits/is_convertible.hpp>
 #include <boost/ref.hpp>
-#include "ParsedCommand.hh"
+#include "Node.hh"
 
 #include "Variables.ih"
 //#include "Variables.mpp"
-///////////////////////////////hh.p////////////////////////////////////////
+//-/////////////////////////////////////////////////////////////////////////////////////////////////
 
 namespace senf {
 namespace console {
@@ -42,66 +42,37 @@ namespace console {
     class ScopedDirectoryBase;
     template <class Variable> class VariableAttributor;
 
-    
+namespace factory {
 
 #ifndef DOXYGEN
 
     template <class Variable>
-    VariableAttributor<Variable> senf_console_add_node(
-        DirectoryNode & node, std::string const & name, Variable & var, int,
-        typename boost::disable_if< boost::is_convertible<Variable*, ScopedDirectoryBase*> >::type * = 0,
-        typename boost::disable_if< boost::is_convertible<Variable*, GenericNode*> >::type * = 0,
-        typename boost::disable_if_c<detail::ParsedCommandTraits<Variable>::is_callable>::type * = 0);
-
-    template <class Variable>
-    typename detail::VariableNodeCreator<Variable>::result_type
-    senf_console_add_node(DirectoryNode & node, std::string const & name, 
-                          boost::reference_wrapper<Variable> var, int);
-
-    template <class Variable, class Owner>
-    VariableAttributor<Variable> senf_console_add_node(
-        DirectoryNode & node, Owner & owner, std::string const & name, Variable & var, int,
-        typename boost::disable_if< boost::is_convertible<Variable*, ScopedDirectoryBase*> >::type * = 0,
-        typename boost::disable_if< boost::is_convertible<Variable*, GenericNode*> >::type * = 0,
-        typename boost::disable_if_c<detail::ParsedCommandTraits<Variable>::is_callable>::type * = 0);
-
-    template <class Variable, class Owner>
-    typename detail::VariableNodeCreator<Variable>::result_type
-    senf_console_add_node(DirectoryNode & node, Owner & owner, std::string const & name, 
-                          boost::reference_wrapper<Variable> var, int);
-
-#endif
-
-    /** \brief Variable command attributes (const)
-        
-        \see VariableAttributor
-     */
-    template <class Variable>
-    class ConstVariableAttributor
+    class ConstVariableFactory
+        : public detail::NodeFactory
     {
     public:
         typedef typename detail::QueryVariable<Variable>::Traits::Overload QueryOverload;
         typedef typename QueryOverload::Formatter Formatter;
         typedef OverloadedCommandNode node_type;
-        typedef ConstVariableAttributor return_type;
+        typedef OverloadedCommandNode & result_type;
 
-        ConstVariableAttributor doc(std::string const & doc);
-        ConstVariableAttributor shortdoc(std::string const & doc);
-        ConstVariableAttributor formatter(Formatter formatter);
+        ConstVariableFactory doc(std::string const & doc);
+        ConstVariableFactory shortdoc(std::string const & doc);
+        ConstVariableFactory formatter(Formatter formatter);
 
-        OverloadedCommandNode & node() const; ///< Return the node object
-        operator OverloadedCommandNode & () const; ///< Automatically convert to node object
+        OverloadedCommandNode & create(DirectoryNode & dir, std::string const & name) const;
 
-    protected:
-        explicit ConstVariableAttributor(QueryOverload & queryOverload);
+        explicit ConstVariableFactory(Variable const & var);
 
     private:
-        QueryOverload & queryOverload_;
-
-        friend class detail::VariableNodeCreator<Variable const>;
+        typename QueryOverload::ptr queryOverload_;
+        boost::optional<std::string> doc_;
+        boost::optional<std::string> shortdoc_;
     };
-    /** \brief Variable command attributes
+
+#endif
+
+    /** \brief Variable node factory
 
         Variable commands allow to register any arbitrary variable as a command node. The variable
         will be registered as two command overloads: One which takes a single argument of the
@@ -111,7 +82,7 @@ namespace console {
             int var;
             ScopedDirectory<> dir;
 
-        dir.add("var", var);
+        dir.add("var", fty::Variable(var));
         \endcode
 
         Variables should be registered only with a ScopedDirectory declared in the same scope
@@ -120,79 +91,101 @@ namespace console {
 
         Since a variable command is added as a combination of two ordinary overloads, it is possible
         to register additional overloads with the same name before or after registering the
-        variable. 
+        variable.
 
         It is also possible, to register a variable read-only. To achieve this, just wrap it with \c
-        boost::cref(). Such a variable cannot be changed only queried. Therefore, it does not have
-        the parser() and typeName() attributes.
+        boost::cref(). Such a variable only queried. Therefore, it does not have the parser() and
+        typeName() attributes.
         \code
-            dir.add("const_var", boost::cref(var))
+            dir.add("const_var", fty::Variable(boost::cref(var)));
         \endcode
 
-        \ingroup console_commands
+        \note Even though the interface is documented as a class, in reality it is implemented using
+            factory functions returning instances of an internal factory class.
+
+        \see \ref console_variables
      */
+#ifdef DOXYGEN
+    class Variable
+#else
     template <class Variable>
-    class VariableAttributor
-        : public ConstVariableAttributor<Variable>
+    class VariableFactory
+        : public ConstVariableFactory<Variable>
+#endif
     {
     public:
         typedef typename detail::SetVariable<Variable>::Traits::Overload SetOverload;
         typedef typename detail::ArgumentInfo<typename SetOverload::arg1_type>::Parser Parser;
         typedef typename detail::SetVariable<Variable>::OnChangeHandler OnChangeHandler;
-        typedef OverloadedCommandNode node_type;
-        typedef VariableAttributor return_type;
-
-        typedef typename ConstVariableAttributor<Variable>::Formatter Formatter;
-        typedef typename ConstVariableAttributor<Variable>::QueryOverload QueryOverload;
-
-        VariableAttributor doc(std::string const & doc); ///< Set documentation of the variable
-        VariableAttributor shortdoc(std::string const & doc); ///< Set short documentation
-        VariableAttributor formatter(Formatter formatter); ///< Set formatter
-        /**< The \a formatter must be a callable with a signature
-             compatible with
-             \code
-                 void formatter(Variable const & value, std::ostream & os);
-             \endcode
-                 The \a formatter takes the return value of the call \a
-                 value and writes it properly formated to \a os. */
-       
-        VariableAttributor parser(Parser parser); ///< Set argument parser
-        /**< The parser is an arbitrary callable object with
-             the signature
-             \code
-                 void parser(senf::console::ParseCommandInfo::TokensRange const & tokens, value_type & out);
-             \endcode
-
-             where \c value_type is the type of the overload
-             parameter. The parser must read and parse the complete
-             \a tokens range and return the parsed value in \a
-             out. If the parser fails, it must raise a
-             senf::console::SyntaxErrorException. */
-        VariableAttributor typeName(std::string const & name); ///< Set name of the variable type
-        VariableAttributor onChange(OnChangeHandler handler); ///< Set change callback
-        /**< The \a handler callback is called, whenever the value
-             of the variable is changed. The new value has already
-             been set, when the callback is called, the old value is
-             passed to the callback. The callback must have a
-             signature compatible to
-             \code
-                 void handler(Variable const & oldValue);
-             \endcode */
+
+        typedef typename ConstVariableFactory<Variable>::Formatter Formatter;
+        typedef typename ConstVariableFactory<Variable>::QueryOverload QueryOverload;
+
+        VariableFactory doc(std::string const & doc); ///< Set documentation of the variable
+        VariableFactory shortdoc(std::string const & doc); ///< Set short documentation
+        VariableFactory formatter(Formatter formatter); ///< Set formatter
+                                        /**< The \a formatter must be a callable with a signature
+                                             compatible with
+                                             \code
+                                                 void formatter(Variable const & value, std::ostream & os);
+                                             \endcode
+                                                 The \a formatter takes the return value of the call \a
+                                                 value and writes it properly formated to \a os. */
+        VariableFactory parser(Parser parser); ///< Set argument parser
+                                        /**< The parser is an arbitrary callable object with
+                                             the signature
+                                             \code
+                                                 void parser(senf::console::ParseCommandInfo::TokensRange const & tokens, value_type & out);
+                                             \endcode
+
+                                             where \c value_type is the type of the overload
+                                             parameter. The parser must read and parse the complete
+                                             \a tokens range and return the parsed value in \a
+                                             out. If the parser fails, it must raise a
+                                             senf::console::SyntaxErrorException. */
+        VariableFactory typeName(std::string const & name); ///< Set name of the variable type
+        VariableFactory onChange(OnChangeHandler handler); ///< Set change callback
+                                        /**< The \a handler callback is called, whenever the value
+                                             of the variable is changed. The new value has already
+                                             been set, when the callback is called, the old value is
+                                             passed to the callback. The callback must have a
+                                             signature compatible to
+                                             \code
+                                                 void handler(Variable const & oldValue);
+                                             \endcode */
+
+        explicit VariableFactory(Variable & var); ///< Create Variable node
+
     protected:
 
     private:
-        VariableAttributor(QueryOverload & queryOverload, SetOverload & setOverload, 
-                           Variable & var);
+        OverloadedCommandNode & create(DirectoryNode & dir, std::string const & name) const;
 
-        SetOverload & setOverload_;
+        typename SetOverload::ptr setOverload_;
         Variable & var_;
 
-        friend class detail::VariableNodeCreator<Variable>;
+        friend class senf::console::DirectoryNode;
     };
-}}
 
-///////////////////////////////hh.e////////////////////////////////////////
+#ifndef DOXYGEN
+
+    template <class Var>
+    VariableFactory<Var> Variable(Var & var);
+
+    template <class Var>
+    VariableFactory<Var> Variable(boost::reference_wrapper<Var> var);
+
+    template <class Var>
+    ConstVariableFactory<Var> Variable(Var const & var);
+
+    template <class Var>
+    ConstVariableFactory<Var> Variable(boost::reference_wrapper<Var const> var);
+
+#endif
+
+}}}
+
+//-/////////////////////////////////////////////////////////////////////////////////////////////////
 //#include "Variables.cci"
 //#include "Variables.ct"
 #include "Variables.cti"