switch to new MPL based Fraunhofer FOKUS Public License
[senf.git] / senf / Utils / membind.hh
1 // $Id$
2 //
3 // Copyright (C) 2006
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at 
9 // http://senf.berlios.de/license.html
10 //
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on, 
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
14 //
15 // Software distributed under the License is distributed on an "AS IS" basis, 
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
17 // for the specific language governing rights and limitations under the License.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. 
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
24 //
25 // Contributor(s):
26 //   Stefan Bund <g0dil@berlios.de>
27
28 /** \file
29     \brief membind  public header */
30
31 /** \defgroup membind Bound Member Functions
32
33     The membind() family of function templates simplifies the creation of simple bound member
34     function pointers:
35
36     \code
37       struct Foo {
38           int test(int x);
39       };
40
41       Foo * foo = ...;
42       boost::function<int (int)> f = senf::membind(&Foo::test,foo);
43       int rv = f(1); // Calls foo->test(1)
44     \endcode
45
46     senf::membind() takes either a pointer or an object as second argument. When passing an object,
47     <em>that object will be copied into the bound member function returned.</em>
48
49     \idea Make the \a ob argument type an additional P template parameter (using call_traits for the
50     exact arg type? Probably we'll get deduction problems then) . The only operation this object
51     must support is ob->*fn. This would allow the use of smart pointers. We should keep the T &
52     version to still support ob.*fn use.
53  */
54
55 #ifndef HH_SENF_Utils_membind_
56 #define HH_SENF_Utils_membind_ 1
57
58 // Custom includes
59 #include <boost/bind.hpp>
60 #include <boost/function.hpp>
61 #include <senf/config.hh>
62
63 //-/////////////////////////////////////////////////////////////////////////////////////////////////
64
65 /** \brief Get function pointer
66
67     This macro will get a function pointer of a possibly overloaded function:
68
69     \code
70     void foo(int i);
71     int foo();
72
73     SENF_FNP(void, foo, (int i)) // Get the address of the first overload
74     \endcode
75
76     The macro arguments are the return type, function name and function arguments just as specified
77     in the declaration.
78
79     This macro only works for functions at namespace scope or for class static functions. For member
80     functions use \ref SENF_MEMFNP() or \ref SENF_MEMBINDFNP().
81
82     \hideinitializer
83     \ingroup membind
84  */
85 #define SENF_FNP(ret, fn, args) \
86     static_cast<ret (*) args>(& fn)
87
88 /** \brief Get function pointer
89
90     This macro will get a member function pointer of a possibly overloaded member function:
91
92     \code
93     struct Foo
94     {
95         void foo(int i);
96         int foo() const;
97     };
98
99     SENF_MEMFNP(int, Foo, foo, () const) // Get the address of the first overload
100     \endcode
101
102     The macro arguments are the return type, class name, function name and function arguments just
103     as specified in the declaration.
104
105     This macro only works for member functions. For namespace scope functions or class static
106     functions use SENF_FNP.
107
108     This macro returns a member function pointer. To automatically bind this pointer to \c this, use
109     \ref SENF_MEMBINDFNP() or use senf::membind() to bind to some other instance besides \c this.
110
111     \hideinitializer
112     \ingroup membind
113  */
114 #define SENF_MEMFNP(ret, cls, fn, args) \
115     static_cast<ret (cls::*) args>(& cls :: fn)
116
117 /** \brief Get function pointer
118
119     This macro will get a member function pointer of a possibly overloaded member function and bind
120     it to \c this returning a boost::function object resembling an ordinary non-member function (see
121     senf::membind()).
122
123     \code
124     struct Foo
125     {
126         void foo(int i);
127         int foo() const;
128
129         Foo()
130         {
131             // Get bound member function for second overload
132             SENF_MEMBINDFNP(int, Foo, foo, () const)
133         }
134
135     };
136     \endcode
137
138     The macro arguments are the return type, class name, function name and function arguments just
139     as specified in the declaration.
140
141     This macro only works for member functions. For namespace scope functions or class static
142     functions use SENF_FNP.
143
144     This macro returns a bound member function (a \c boost::function object instance). To get an
145     ordinary member function pointer use \ref SENF_MEMFNP(), for non-member function or class static
146     functions use \ref MEM_FNP().
147
148     \hideinitializer
149     \ingroup membind
150  */
151 #define SENF_MEMBINDFNP(ret, cls, fn, args) \
152     senf::membind(SENF_MEMFNP(ret, cls, fn, args), this)
153
154 namespace senf {
155
156 #define scOBTYPE *
157 #include <senf/Utils/impl/membind.hh>
158 #undef scOBTYPE
159
160 #define scOBTYPE &
161 #include <senf/Utils/impl/membind.hh>
162 #undef scOBTYPE
163
164 #ifdef DOXYGEN
165
166     /// \addtogroup membind
167     //\{
168
169     /** \brief Build bound member function object
170
171         membind() supports up to 9 function parameters (represented as
172         \a Args here). The \a ob argument can be either a pointer or a
173         reference to \a T
174         \param[in] fn member function pointer
175         \param[in] ob object instance to bind this pointer to
176         \returns Boost.Function object representing a bound call of \a
177             fn on \a ob
178      */
179     template <typename R, typename T, typename Args>
180     boost::function<R (Args)> membind(R (T::* fn)( Args ), T * ob);
181
182     //\}
183
184 #endif
185
186 }
187
188 //-/////////////////////////////////////////////////////////////////////////////////////////////////
189 //#include "membind.cci"
190 //#include "membind.ct"
191 //#include "membind.cti"
192 #endif
193
194 \f
195 // Local Variables:
196 // mode: c++
197 // fill-column: 100
198 // c-file-style: "senf"
199 // indent-tabs-mode: nil
200 // ispell-local-dictionary: "american"
201 // compile-command: "scons -u test"
202 // comment-column: 40
203 // End: