From 5424e25a2c9092a7e85dc26da42141efbe07e669 Mon Sep 17 00:00:00 2001
From: g0dil <g0dil@wiback.org>
Date: Fri, 14 Nov 2008 15:02:55 +0000
Subject: [PATCH] Scheduler/Console: Fix overload resolution order when adding
 parsed commands

---
 Scheduler/Console/ParsedCommand.cti   |  3 ++-
 Scheduler/Console/ParsedCommand.hh    |  4 +++-
 Scheduler/Console/ParsedCommand.ih    |  6 +++++-
 Scheduler/Console/ScopedDirectory.cti |  2 +-
 Scheduler/Console/ScopedDirectory.hh  |  3 ++-
 Scheduler/Console/Variables.cti       | 17 ++++++++++++++---
 Scheduler/Console/Variables.hh        | 11 +++++++++--
 Scheduler/Console/Variables.test.cc   |  5 +----
 Utils/type_traits.hh                  | 10 ++++++++++
 9 files changed, 47 insertions(+), 14 deletions(-)

diff --git a/Scheduler/Console/ParsedCommand.cti b/Scheduler/Console/ParsedCommand.cti
index a3f2618c1..eeedd3a30 100644
--- a/Scheduler/Console/ParsedCommand.cti
+++ b/Scheduler/Console/ParsedCommand.cti
@@ -373,7 +373,8 @@ namespace detail {
 template <class Function>
 typename senf::console::detail::ParsedCommandTraits<Function>::Attributor
 senf::console::senf_console_add_node(DirectoryNode & node, std::string const & name,
-                                     Function fn, int)
+                                     Function fn, int,
+                                     typename boost::enable_if_c<detail::ParsedCommandTraits<Function>::is_callable>::type *)
 {
     return senf::console::detail::addOverloadedCommandNode<Function>(node, name, fn);
 }
diff --git a/Scheduler/Console/ParsedCommand.hh b/Scheduler/Console/ParsedCommand.hh
index 107ed65a0..6604dd348 100644
--- a/Scheduler/Console/ParsedCommand.hh
+++ b/Scheduler/Console/ParsedCommand.hh
@@ -565,7 +565,9 @@ namespace console {
 
     template <class Function>
     typename detail::ParsedCommandTraits<Function>::Attributor
-    senf_console_add_node(DirectoryNode & node, std::string const & name, Function fn, int);
+    senf_console_add_node(DirectoryNode & node, std::string const & name, Function fn, int,
+                          typename boost::enable_if_c<
+                              detail::ParsedCommandTraits<Function>::is_callable>::type * = 0);
 
     template <class Signature>
     typename detail::ParsedCommandTraits<Signature>::Attributor
diff --git a/Scheduler/Console/ParsedCommand.ih b/Scheduler/Console/ParsedCommand.ih
index 330ea7c42..c33944520 100644
--- a/Scheduler/Console/ParsedCommand.ih
+++ b/Scheduler/Console/ParsedCommand.ih
@@ -112,7 +112,10 @@ namespace detail {
 
     template <class FnunctionP, class Function, bool isFN=boost::is_function<Function>::value>
     struct ParsedCommandTraits_i
-    {};
+    {
+        static const bool is_callable = false;
+        static const bool is_member = false;
+    };
 
     template <class FunctionP, class Function>
     struct ParsedCommandTraits_i<FunctionP, Function, true>
@@ -132,6 +135,7 @@ namespace detail {
 
         typedef typename senf::remove_cvref<typename base_traits::result_type>::type result_type;
 
+        static const bool is_callable = true;
         static const bool is_member = boost::is_member_pointer<base_type>::value;
         
         typedef typename senf::member_class<base_type>::type class_type;
diff --git a/Scheduler/Console/ScopedDirectory.cti b/Scheduler/Console/ScopedDirectory.cti
index 40c7e2558..6fedea2d3 100644
--- a/Scheduler/Console/ScopedDirectory.cti
+++ b/Scheduler/Console/ScopedDirectory.cti
@@ -75,7 +75,7 @@ senf::console::ScopedDirectory<Owner>::add(std::string const & name, Object & ob
 template <class Owner, class Function>
 prefix_ senf::console::SimpleCommandNode & senf::console::
 senf_console_add_node(DirectoryNode & node, Owner & , std::string const & name,
-                      Function const & fn, ...)
+                      SimpleCommandNode::Function fn, int)
 {
     return node.add(name,fn);
 }
diff --git a/Scheduler/Console/ScopedDirectory.hh b/Scheduler/Console/ScopedDirectory.hh
index c0f3bb9f4..f82375aff 100644
--- a/Scheduler/Console/ScopedDirectory.hh
+++ b/Scheduler/Console/ScopedDirectory.hh
@@ -189,7 +189,8 @@ namespace console {
 
     template <class Owner, class Function>
     SimpleCommandNode & senf_console_add_node(
-        DirectoryNode & node, Owner & owner, std::string const & name, Function const & fn, ...);
+        DirectoryNode & node, Owner & owner, std::string const & name,
+        SimpleCommandNode::Function fn, int);
 
     template <class Owner>
     SimpleCommandNode & senf_console_add_node(
diff --git a/Scheduler/Console/Variables.cti b/Scheduler/Console/Variables.cti
index ef846d5de..f6839be1f 100644
--- a/Scheduler/Console/Variables.cti
+++ b/Scheduler/Console/Variables.cti
@@ -182,7 +182,8 @@ senf::console::detail::VariableNodeCreator<Variable, true>::add(DirectoryNode &
 template <class Variable>
 prefix_ senf::console::VariableAttributor<Variable> senf::console::
 senf_console_add_node(DirectoryNode & node, std::string const & name, Variable & var, int,
-                      typename boost::disable_if< boost::is_convertible<Variable*, ScopedDirectoryBase*> >::type *)
+                      typename boost::disable_if< boost::is_convertible<Variable*, ScopedDirectoryBase*> >::type *,
+                      typename boost::disable_if_c<detail::ParsedCommandTraits<Variable>::is_callable>::type *)
 {
     return detail::VariableNodeCreator<Variable>::add(node, name, var);
 }
@@ -197,13 +198,23 @@ senf::console::senf_console_add_node(DirectoryNode & node, std::string const & n
 
 template <class Variable, class Owner>
 prefix_ senf::console::VariableAttributor<Variable> senf::console::
-senf_console_add_node(DirectoryNode & node, Owner & owner, std::string const & name,
+senf_console_add_node(DirectoryNode & node, Owner &, std::string const & name,
                       Variable & var, int,
-                      typename boost::disable_if< boost::is_convertible<Variable*, ScopedDirectoryBase*> >::type *)
+                      typename boost::disable_if< boost::is_convertible<Variable*, ScopedDirectoryBase*> >::type *,
+                      typename boost::disable_if_c<detail::ParsedCommandTraits<Variable>::is_callable>::type *)
 {
     return detail::VariableNodeCreator<Variable>::add(node, name, var);
 }
 
+template <class Variable, class Owner>
+prefix_ typename senf::console::detail::VariableNodeCreator<Variable>::result_type
+senf::console::senf_console_add_node(DirectoryNode & node, Owner &,
+                                     std::string const & name,
+                                     boost::reference_wrapper<Variable> var, int)
+{
+    return detail::VariableNodeCreator<Variable>::add(node, name, var.get());
+}
+
 #endif
 
 ///////////////////////////////cti.e///////////////////////////////////////
diff --git a/Scheduler/Console/Variables.hh b/Scheduler/Console/Variables.hh
index 74db97c78..d8a946801 100644
--- a/Scheduler/Console/Variables.hh
+++ b/Scheduler/Console/Variables.hh
@@ -47,7 +47,8 @@ namespace console {
     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*, ScopedDirectoryBase*> >::type * = 0,
+        typename boost::disable_if_c<detail::ParsedCommandTraits<Variable>::is_callable>::type * = 0);
 
     template <class Variable>
     typename detail::VariableNodeCreator<Variable>::result_type
@@ -57,7 +58,13 @@ namespace console {
     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*, ScopedDirectoryBase*> >::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
 
diff --git a/Scheduler/Console/Variables.test.cc b/Scheduler/Console/Variables.test.cc
index 58348f784..9bc58cda8 100644
--- a/Scheduler/Console/Variables.test.cc
+++ b/Scheduler/Console/Variables.test.cc
@@ -29,10 +29,7 @@
 // Custom includes
 #include <iostream>
 #include <sstream>
-#include "Variables.hh"
-#include "Executor.hh"
-#include "Parse.hh"
-#include "ScopedDirectory.hh"
+#include "Console.hh"
 
 #include "../../Utils/auto_unit_test.hh"
 #include <boost/test/test_tools.hpp>
diff --git a/Utils/type_traits.hh b/Utils/type_traits.hh
index 34451b4c1..1e9667b40 100644
--- a/Utils/type_traits.hh
+++ b/Utils/type_traits.hh
@@ -131,6 +131,11 @@ namespace senf
         typedef T type;
     };
 
+    template < class C, class T > struct remove_member_pointer <T (C::* const) >
+    {
+        typedef T type;
+    };
+
 #endif
 
     /** \brief Get class of a member pointer
@@ -163,6 +168,11 @@ namespace senf
         typedef C type;
     };
 
+    template < class C, class T > struct member_class <T (C::* const) >
+    {
+        typedef C type;
+    };
+
 #endif
 
     /** \brief Remove any type of pointer from type
-- 
GitLab