c++-gtk-utils

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

mem_fun.h
Go to the documentation of this file.
1 /* Copyright (C) 2009 Chris Vine
2
3 The library comprised in this file or of which this file is part is
4 distributed by Chris Vine under the GNU Lesser General Public
5 License as follows:
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public License
9 as published by the Free Software Foundation; either version 2.1 of
10 the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License, version 2.1, for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License, version 2.1, along with this library (see the file LGPL.TXT
19 which came with this source code package in the c++-gtk-utils
20 sub-directory); if not, write to the Free Software Foundation, Inc.,
21 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22
23 However, it is not intended that the object code of a program whose
24 source code instantiates a template from this file or uses macros or
25 inline functions (of any length) should by reason only of that
26 instantiation or use be subject to the restrictions of use in the GNU
27 Lesser General Public License. With that in mind, the words "and
28 macros, inline functions and instantiations of templates (of any
29 length)" shall be treated as substituted for the words "and small
30 macros and small inline functions (ten lines or less in length)" in
31 the fourth paragraph of section 5 of that licence. This does not
32 affect any other reason why object code may be subject to the
33 restrictions in that licence (nor for the avoidance of doubt does it
34 affect the application of section 2 of that licence to modifications
35 of the source code in this file).
36
37 */
38
39 #ifndef CGU_MEM_FUN_H
40 #define CGU_MEM_FUN_H
41
42 /**
43 * @file mem_fun.h
44 * @brief This file contains an adaptor to create a functor from a
45 * class member function to pass to C++ standard algorithms.
46 *
47 * \#include <c++-gtk-utils/mem_fun.h>
48 *
49 * Cgu::MemFun::make() is provided in order to provide source
50 * compatibility with the 1.2 series of the library. In C++11 it is
51 * superseded by std::mem_fn() and std::bind.
52 *
53 * Cgu::MemFun::make() is an adaptor which allows a non-static class
54 * member function to be called by standard algorithms such as
55 * std::for_each() or std::transform(), whereby the member function is
56 * passed a contained object as an argument on iterating through the
57 * container. It can also be used to make predicates from member
58 * functions to pass to other algorithms, or indeed to generate a
59 * general functor object representing a member function with object
60 * and one or two arguments. It does the equivalent of std::ptr_fun()
61 * for ordinary functions.
62 *
63 * For example, to iterate over a std::vector<int> container object
64 * named 'vec', calling a class method 'void MyObj::my_method(int)' on
65 * each iteration, Cgu::MemFun::make() could be invoked as:
66 *
67 * @code
68 * using namespace Cgu;
69 * std::for_each(vec.begin(), vec.end(),
70 * MemFun::make(my_obj, &MyObj::my_method));
71 * @endcode
72 *
73 * As in the case of std::ptr_fun(), when called via std::for_each(),
74 * the member function called must be a unary function, although an
75 * additional argument can be bound with std::bind2nd() or
76 * std::bind1st() to enable it to be used with binary class functions.
77 * (Note that in many implementations of std::bind1st/2nd, neither the
78 * free nor the bound argument can be a reference, whether const or
79 * non-const. A reference argument can be employed with
80 * Cgu::MemFun::make() where std::bind1st/2nd is not used.) This
81 * limitation with respect to reference arguments is not present with
82 * std::mem_fn() and std::bind.
83 *
84 * In C++11, the above example could be reproduced as:
85 *
86 * @code
87 * using namespace std::placeholders; // for _1
88 * std::for_each(vec.begin(), vec.end(),
89 * std::bind(&MyObj::my_method, &my_obj, _1));
90 * @endcode
91 */
92
93 /**
94 * @namespace Cgu::MemFun
95 * @brief This namespace contains an adaptor to create a functor from a
96 * class member function to pass to C++ standard algorithms.
97 *
98 * \#include <c++-gtk-utils/mem_fun.h>
99 *
100 * Cgu::MemFun::make() is provided in order to provide source
101 * compatibility with the 1.2 series of the library. In C++11 it is
102 * superseded by std::mem_fn() and std::bind.
103 *
104 * Cgu::MemFun::make() is an adaptor which allows a non-static class
105 * member function to be called by standard algorithms such as
106 * std::for_each() or std::transform(), whereby the member function is
107 * passed a contained object as an argument on iterating through the
108 * container. It can also be used to make predicates from member
109 * functions to pass to other algorithms, or indeed to generate a
110 * general functor object representing a member function with object
111 * and one or two arguments. It does the equivalent of std::ptr_fun()
112 * for ordinary functions.
113 *
114 * For example, to iterate over a std::vector<int> container object
115 * named 'vec', calling a class method 'void MyObj::my_method(int)' on
116 * each iteration, Cgu::MemFun::make() could be invoked as:
117 *
118 * @code
119 * using namespace Cgu;
120 * std::for_each(vec.begin(), vec.end(),
121 * MemFun::make(my_obj, &MyObj::my_method));
122 * @endcode
123 *
124 * As in the case of std::ptr_fun(), when called via std::for_each(),
125 * the member function called must be a unary function, although an
126 * additional argument can be bound with std::bind2nd() or
127 * std::bind1st() to enable it to be used with binary class functions.
128 * (Note that in many implementations of std::bind1st/2nd, neither the
129 * free nor the bound argument can be a reference, whether const or
130 * non-const. A reference argument can be employed with
131 * Cgu::MemFun::make() where std::bind1st/2nd is not used.) This
132 * limitation with respect to reference arguments is not present with
133 * std::mem_fn() and std::bind.
134 *
135 * In C++11, the above example could be reproduced as:
136 *
137 * @code
138 * using namespace std::placeholders; // for _1
139 * std::for_each(vec.begin(), vec.end(),
140 * std::bind(&MyObj::my_method, &my_obj, _1));
141 * @endcode
142 */
143
144 #include <functional>
145 #include <c++-gtk-utils/cgu_config.h>
146
147 namespace Cgu {
148
149 namespace MemFun {
150
151 template <class Ret, class Arg, class T>
152 class Functor1: public std::unary_function<Arg, Ret> {
153 T* obj;
154 Ret (T::*func)(Arg);
155 public:
156 Ret operator()(Arg arg) const {return (obj->*func)(arg);}
157 Functor1(T& obj_, Ret (T::*func_)(Arg)): obj(&obj_), func(func_) {}
158 };
159
160 template <class Ret, class Arg, class T>
161 Functor1<Ret, Arg, T> make(T& t,
162 Ret (T::*func)(Arg)) {
163 return Functor1<Ret, Arg, T>(t, func);
164 }
165
166 /* const version, for binding to const methods */
167
168 template <class Ret, class Arg, class T>
169 class Functor1_const: public std::unary_function<Arg, Ret> {
170 const T* obj;
171 Ret (T::*func)(Arg) const;
172 public:
173 Ret operator()(Arg arg) const {return (obj->*func)(arg);}
174 Functor1_const(const T& obj_, Ret (T::*func_)(Arg) const): obj(&obj_), func(func_) {}
175 };
176
177 template <class Ret, class Arg, class T>
178 Functor1_const<Ret, Arg, T> make(const T& t,
179 Ret (T::*func)(Arg) const) {
180 return Functor1_const<Ret, Arg, T>(t, func);
181 }
182
183 /* two argument version for use with std::bind* */
184
185 template <class Ret, class Arg1, class Arg2, class T>
186 class Functor2: public std::binary_function<Arg1, Arg2, Ret> {
187 T* obj;
188 Ret (T::*func)(Arg1, Arg2);
189 public:
190 Ret operator()(Arg1 arg1, Arg2 arg2) const {return (obj->*func)(arg1, arg2);}
191 Functor2(T& obj_, Ret (T::*func_)(Arg1, Arg2)): obj(&obj_), func(func_) {}
192 };
193
194 template <class Ret, class Arg1, class Arg2, class T>
195 Functor2<Ret, Arg1, Arg2, T> make(T& t,
196 Ret (T::*func)(Arg1, Arg2)) {
197 return Functor2<Ret, Arg1, Arg2, T>(t, func);
198 }
199
200 /* const version, for binding to const methods */
201
202 template <class Ret, class Arg1, class Arg2, class T>
203 class Functor2_const: public std::binary_function<Arg1, Arg2, Ret> {
204 const T* obj;
205 Ret (T::*func)(Arg1, Arg2) const;
206 public:
207 Ret operator()(Arg1 arg1, Arg2 arg2) const {return (obj->*func)(arg1, arg2);}
208 Functor2_const(const T& obj_, Ret (T::*func_)(Arg1, Arg2) const): obj(&obj_), func(func_) {}
209 };
210
211 template <class Ret, class Arg1, class Arg2, class T>
212 Functor2_const<Ret, Arg1, Arg2, T> make(const T& t,
213 Ret (T::*func)(Arg1, Arg2) const) {
214 return Functor2_const<Ret, Arg1, Arg2, T>(t, func);
215 }
216
217 } // namespace MemFun
218
219 } // namespace Cgu
220
221 #endif