c++-gtk-utils
mem_fun.h
Go to the documentation of this file.
1 /* Copyright (C) 2009 and 2014 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/14 it
51  * is 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/14, 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/14 it
102  * is 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/14, 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>
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>
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>
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>
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>
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
Cgu::MemFun::make
Functor1< Ret, Arg, T > make(T &t, Ret(T::*func)(Arg))
Definition: mem_fun.h:161
Cgu
Definition: application.h:44
Cgu::MemFun::Functor1::operator()
Ret operator()(Arg arg) const
Definition: mem_fun.h:156
Cgu::MemFun::Functor2_const::Functor2_const
Functor2_const(const T &obj_, Ret(T::*func_)(Arg1, Arg2) const)
Definition: mem_fun.h:208
Cgu::MemFun::Functor2_const::operator()
Ret operator()(Arg1 arg1, Arg2 arg2) const
Definition: mem_fun.h:207
Cgu::MemFun::Functor2_const
Definition: mem_fun.h:203
Cgu::MemFun::Functor2::operator()
Ret operator()(Arg1 arg1, Arg2 arg2) const
Definition: mem_fun.h:190
Cgu::MemFun::Functor1_const::Functor1_const
Functor1_const(const T &obj_, Ret(T::*func_)(Arg) const)
Definition: mem_fun.h:174
Cgu::MemFun::Functor2
Definition: mem_fun.h:186
Cgu::MemFun::Functor1_const
Definition: mem_fun.h:169
Cgu::MemFun::Functor1
Definition: mem_fun.h:152
Cgu::MemFun::Functor1_const::operator()
Ret operator()(Arg arg) const
Definition: mem_fun.h:173
Cgu::MemFun::Functor1::Functor1
Functor1(T &obj_, Ret(T::*func_)(Arg))
Definition: mem_fun.h:157
Cgu::MemFun::Functor2::Functor2
Functor2(T &obj_, Ret(T::*func_)(Arg1, Arg2))
Definition: mem_fun.h:191
cgu_config.h