Utils: (membind) Fix weird casting error when binding base-class members
[senf.git] / Utils / membind.hh
index fdb56f4..3b1c4f7 100644 (file)
@@ -1,9 +1,9 @@
 // $Id$
 //
 // Copyright (C) 2006
-// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
-// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
-//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+//     Stefan Bund <g0dil@berlios.de>
 //
 // This program is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
@@ -25,8 +25,8 @@
 
 /** \defgroup membind Bound Member Functions
 
-    The membind() family of function templates simplifies the creation
-    of simple bound member function pointers:
+    The membind() family of function templates simplifies the creation of simple bound member
+    function pointers:
 
     \code
       struct Foo {
       int rv = f(1); // Calls foo->test(1)
     \endcode
 
-    \idea Make the \a ob argument type an additional P template
-    parameter (using call_traits for the exact arg type? Probably
-    we'll get deduction problems then) . The only operation this
-    object musst suppoprt is ob->*fn. This would allow the use of
-    smart pointers. We should keep the T & version to still support
-    ob.*fn use.
+    senf::membind() takes either a pointer or an object as second argument. When passing an object,
+    <em>that object will be copied into the bound member function returned.</em>
+
+    \idea Make the \a ob argument type an additional P template parameter (using call_traits for the
+    exact arg type? Probably we'll get deduction problems then) . The only operation this object
+    must support is ob->*fn. This would allow the use of smart pointers. We should keep the T &
+    version to still support ob.*fn use.
  */
 
-#ifndef HH_membind_
-#define HH_membind_ 1
+#ifndef HH_SENF_Utils_membind_
+#define HH_SENF_Utils_membind_ 1
 
 // Custom includes
 #include <boost/bind.hpp>
 #include <boost/function.hpp>
+#include "../config.hh"
 
 ///////////////////////////////hh.p////////////////////////////////////////
 
+/** \brief Get function pointer
+
+    This macro will get a function pointer of a possibly overloaded function:
+
+    \code
+    void foo(int i);
+    int foo();
+
+    SENF_FNP(void, foo, (int i)) // Get the address of the first overload
+    \endcode
+
+    The macro arguments are the return type, function name and function arguments just as specified
+    in the declaration.
+
+    This macro only works for functions at namespace scope or for class static functions. For member
+    functions use \ref SENF_MEMFNP() or \ref SENF_MEMBINDFNP().
+
+    \hideinitializer
+    \ingroup membind
+ */
+#define SENF_FNP(ret, fn, args) \
+    static_cast<ret (*) args>(& fn)
+
+/** \brief Get function pointer
+
+    This macro will get a member function pointer of a possibly overloaded member function:
+
+    \code
+    struct Foo
+    {
+        void foo(int i);
+        int foo() const;
+    };
+
+    SENF_MEMFNP(int, Foo, foo, () const) // Get the address of the first overload
+    \endcode
+
+    The macro arguments are the return type, class name, function name and function arguments just
+    as specified in the declaration.
+
+    This macro only works for member functions. For namespace scope functions or class static
+    functions use SENF_FNP.
+
+    This macro returns a member function pointer. To automatically bind this pointer to \c this, use
+    \ref SENF_MEMBINDFNP() or use senf::membind() to bind to some other instance besides \c this.
+
+    \hideinitializer
+    \ingroup membind
+ */
+#define SENF_MEMFNP(ret, cls, fn, args) \
+    static_cast<ret (cls::*) args>(& cls :: fn)
+
+/** \brief Get function pointer
+
+    This macro will get a member function pointer of a possibly overloaded member function and bind
+    it to \c this returning a boost::function object resembling an ordinary non-member function (see
+    senf::membind()).
+
+    \code
+    struct Foo
+    {
+        void foo(int i);
+        int foo() const;
+
+        Foo()
+        {
+            // Get bound member function for second overload
+            SENF_MEMBINDFNP(int, Foo, foo, () const) 
+        }
+    
+    };
+    \endcode
+
+    The macro arguments are the return type, class name, function name and function arguments just
+    as specified in the declaration.
+
+    This macro only works for member functions. For namespace scope functions or class static
+    functions use SENF_FNP.
+
+    This macro returns a bound member function (a \c boost::function object instance). To get an
+    ordinary member function pointer use \ref SENF_MEMFNP(), for non-member function or class static
+    functions use \ref MEM_FNP().
+
+    \hideinitializer
+    \ingroup membind
+ */
+#define SENF_MEMBINDFNP(ret, cls, fn, args) \
+    senf::membind(SENF_MEMFNP(ret, cls, fn, args), this)
+
 namespace senf {
 
-#define scOBTYPE T *
-#include "Utils/impl/membind.hh"
+#define scOBTYPE *
+#include "../Utils/impl/membind.hh"
 #undef scOBTYPE
 
-#define scOBTYPE T &
-#include "Utils/impl/membind.hh"
+#define scOBTYPE &
+#include "../Utils/impl/membind.hh"
 #undef scOBTYPE
 
 #ifdef DOXYGEN
@@ -102,4 +193,6 @@ namespace senf {
 // c-file-style: "senf"
 // indent-tabs-mode: nil
 // ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// comment-column: 40
 // End: