c++-gtk-utils
mem_fun.h
Go to the documentation of this file.
00001 /* Copyright (C) 2009 Chris Vine
00002 
00003 The library comprised in this file or of which this file is part is
00004 distributed by Chris Vine under the GNU Lesser General Public
00005 License as follows:
00006 
00007    This library is free software; you can redistribute it and/or
00008    modify it under the terms of the GNU Lesser General Public License
00009    as published by the Free Software Foundation; either version 2.1 of
00010    the License, or (at your option) any later version.
00011 
00012    This library is distributed in the hope that it will be useful, but
00013    WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015    Lesser General Public License, version 2.1, for more details.
00016 
00017    You should have received a copy of the GNU Lesser General Public
00018    License, version 2.1, along with this library (see the file LGPL.TXT
00019    which came with this source code package in the c++-gtk-utils
00020    sub-directory); if not, write to the Free Software Foundation, Inc.,
00021    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00022 
00023 However, it is not intended that the object code of a program whose
00024 source code instantiates a template from this file or uses macros or
00025 inline functions (of any length) should by reason only of that
00026 instantiation or use be subject to the restrictions of use in the GNU
00027 Lesser General Public License.  With that in mind, the words "and
00028 macros, inline functions and instantiations of templates (of any
00029 length)" shall be treated as substituted for the words "and small
00030 macros and small inline functions (ten lines or less in length)" in
00031 the fourth paragraph of section 5 of that licence.  This does not
00032 affect any other reason why object code may be subject to the
00033 restrictions in that licence (nor for the avoidance of doubt does it
00034 affect the application of section 2 of that licence to modifications
00035 of the source code in this file).
00036 
00037 */
00038 
00039 #ifndef CGU_MEM_FUN_H
00040 #define CGU_MEM_FUN_H
00041 
00042 /**
00043  * @file mem_fun.h
00044  * @brief This file contains an adaptor to create a functor from a
00045  * class member function to pass to C++ standard algorithms.
00046  *
00047  * \#include <c++-gtk-utils/mem_fun.h>
00048  *
00049  * Cgu::MemFun::make() is provided in order to provide source
00050  * compatibility with the 1.2 series of the library.  In C++11 it is
00051  * superseded by std::function, std::mem_fn() and std::bind.
00052  *
00053  * Cgu::MemFun::make() is an adaptor which allows a non-static class
00054  * member function to be called by standard algorithms such as
00055  * std::for_each() or std::transform(), whereby the member function is
00056  * passed a contained object as an argument on iterating through the
00057  * container.  It can also be used to make predicates from member
00058  * functions to pass to other algorithms, or indeed to generate a
00059  * general functor object representing a member function with object
00060  * and one or two arguments.  It does the equivalent of std::ptr_fun()
00061  * for ordinary functions.
00062  *
00063  * For example, to iterate over a std::vector<int> container object
00064  * named 'vec', calling a class method 'void MyObj::my_method(int)' on
00065  * each iteration, Cgu::MemFun::make() could be invoked as:
00066  *
00067  * @code 
00068  * using namespace Cgu;
00069  * std::for_each(vec.begin(), vec.end(),
00070  *               MemFun::make(my_obj, &MyObj::my_method));
00071  * @endcode 
00072  *
00073  * As in the case of std::ptr_fun(), when called via std::for_each(),
00074  * the member function called must be a unary function, although an
00075  * additional argument can be bound with std::bind2nd() or
00076  * std::bind1st() to enable it to be used with binary class functions.
00077  * (Note that in many implementations of std::bind1st/2nd, neither the
00078  * free nor the bound argument can be a reference, whether const or
00079  * non-const.  A reference argument can be employed with
00080  * Cgu::MemFun::make() where std::bind1st/2nd is not used.)  This
00081  * limitation with respect to reference arguments is not present with
00082  * std::mem_fn() and std::bind.
00083  *
00084  * In C++11, the above example could be reproduced as:
00085  *
00086  * @code
00087  * using namespace std::placeholders;  // for _1
00088  * std::for_each(vec.begin(), vec.end(),
00089  *               std::bind(std::mem_fn(&MyObj::my_method), &my_obj, _1));
00090  * @endcode 
00091  */
00092 
00093 /**
00094  * @namespace Cgu::MemFun
00095  * @brief This namespace contains an adaptor to create a functor from a
00096  * class member function to pass to C++ standard algorithms.
00097  *
00098  * \#include <c++-gtk-utils/mem_fun.h>
00099  *
00100  * Cgu::MemFun::make() is provided in order to provide source
00101  * compatibility with the 1.2 series of the library.  In C++11 it is
00102  * superseded by std::function, std::mem_fn() and std::bind.
00103  *
00104  * Cgu::MemFun::make() is an adaptor which allows a non-static class
00105  * member function to be called by standard algorithms such as
00106  * std::for_each() or std::transform(), whereby the member function is
00107  * passed a contained object as an argument on iterating through the
00108  * container.  It can also be used to make predicates from member
00109  * functions to pass to other algorithms, or indeed to generate a
00110  * general functor object representing a member function with object
00111  * and one or two arguments.  It does the equivalent of std::ptr_fun()
00112  * for ordinary functions.
00113  *
00114  * For example, to iterate over a std::vector<int> container object
00115  * named 'vec', calling a class method 'void MyObj::my_method(int)' on
00116  * each iteration, Cgu::MemFun::make() could be invoked as:
00117  *
00118  * @code 
00119  * using namespace Cgu;
00120  * std::for_each(vec.begin(), vec.end(),
00121  *               MemFun::make(my_obj, &MyObj::my_method));
00122  * @endcode 
00123  *
00124  * As in the case of std::ptr_fun(), when called via std::for_each(),
00125  * the member function called must be a unary function, although an
00126  * additional argument can be bound with std::bind2nd() or
00127  * std::bind1st() to enable it to be used with binary class functions.
00128  * (Note that in many implementations of std::bind1st/2nd, neither the
00129  * free nor the bound argument can be a reference, whether const or
00130  * non-const.  A reference argument can be employed with
00131  * Cgu::MemFun::make() where std::bind1st/2nd is not used.)  This
00132  * limitation with respect to reference arguments is not present with
00133  * std::mem_fn() and std::bind.
00134  *
00135  * In C++11, the above example could be reproduced as:
00136  *
00137  * @code
00138  * using namespace std::placeholders;  // for _1
00139  * std::for_each(vec.begin(), vec.end(),
00140  *               std::bind(std::mem_fn(&MyObj::my_method), &my_obj, _1));
00141  * @endcode 
00142  */
00143 
00144 #include <functional>
00145 #include <c++-gtk-utils/cgu_config.h>
00146 
00147 namespace Cgu {
00148 
00149 namespace MemFun {
00150 
00151 template <class Ret, class Arg, class T>
00152 class Functor1: public std::unary_function<Arg, Ret> {
00153   T* obj;
00154   Ret (T::*func)(Arg);
00155 public:
00156   Ret operator()(Arg arg) const {return (obj->*func)(arg);}
00157   Functor1(T& obj_, Ret (T::*func_)(Arg)): obj(&obj_), func(func_) {}
00158 };
00159 
00160 template <class Ret, class Arg, class T>
00161 Functor1<Ret, Arg, T> make(T& t,
00162                            Ret (T::*func)(Arg)) {
00163   return Functor1<Ret, Arg, T>(t, func);
00164 }
00165 
00166 /* const version, for binding to const methods */
00167 
00168 template <class Ret, class Arg, class T>
00169 class Functor1_const: public std::unary_function<Arg, Ret> {
00170   const T* obj;
00171   Ret (T::*func)(Arg) const;
00172 public:
00173   Ret operator()(Arg arg) const {return (obj->*func)(arg);}
00174   Functor1_const(const T& obj_, Ret (T::*func_)(Arg) const): obj(&obj_), func(func_) {}
00175 };
00176 
00177 template <class Ret, class Arg, class T>
00178 Functor1_const<Ret, Arg, T> make(const T& t,
00179                                  Ret (T::*func)(Arg) const) {
00180   return Functor1_const<Ret, Arg, T>(t, func);
00181 }
00182 
00183 /* two argument version for use with std::bind* */
00184 
00185 template <class Ret, class Arg1, class Arg2, class T>
00186 class Functor2: public std::binary_function<Arg1, Arg2, Ret> {
00187   T* obj;
00188   Ret (T::*func)(Arg1, Arg2);
00189 public:
00190   Ret operator()(Arg1 arg1, Arg2 arg2) const {return (obj->*func)(arg1, arg2);}
00191   Functor2(T& obj_, Ret (T::*func_)(Arg1, Arg2)): obj(&obj_), func(func_) {}
00192 };
00193 
00194 template <class Ret, class Arg1, class Arg2, class T>
00195 Functor2<Ret, Arg1, Arg2, T> make(T& t,
00196                                   Ret (T::*func)(Arg1, Arg2)) {
00197   return Functor2<Ret, Arg1, Arg2, T>(t, func);
00198 }
00199 
00200 /* const version, for binding to const methods */
00201 
00202 template <class Ret, class Arg1, class Arg2, class T>
00203 class Functor2_const: public std::binary_function<Arg1, Arg2, Ret> {
00204   const T* obj;
00205   Ret (T::*func)(Arg1, Arg2) const;
00206 public:
00207   Ret operator()(Arg1 arg1, Arg2 arg2) const {return (obj->*func)(arg1, arg2);}
00208   Functor2_const(const T& obj_, Ret (T::*func_)(Arg1, Arg2) const): obj(&obj_), func(func_) {}
00209 };
00210 
00211 template <class Ret, class Arg1, class Arg2, class T>
00212 Functor2_const<Ret, Arg1, Arg2, T> make(const T& t,
00213                                         Ret (T::*func)(Arg1, Arg2) const) {
00214   return Functor2_const<Ret, Arg1, Arg2, T>(t, func);
00215 }
00216 
00217 } // namespace MemFun
00218 
00219 } // namespace Cgu
00220 
00221 #endif