Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

more/gen/functional.h

Go to the documentation of this file.
00001 //  Copyright (C) 1998--2001  Petter Urkedal (petter.urkedal@matfys.lth.se)
00002 //
00003 //  This file is free software; you can redistribute it and/or modify
00004 //  it under the terms of the GNU General Public License as published by
00005 //  the Free Software Foundation; either version 2 of the License, or
00006 //  (at your option) any later version.
00007 //
00008 //  This file is distributed in the hope that it will be useful,
00009 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011 //  GNU General Public License for more details.
00012 //
00013 //  You should have received a copy of the GNU General Public License
00014 //  along with this program; if not, write to the Free Software
00015 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00016 //
00017 //  As a special exception, you may use this file as part of a free
00018 //  software library without restriction.  Specifically, if other files
00019 //  instantiate templates or use macros or inline functions from this
00020 //  file, or you compile this file and link it with other files to
00021 //  produce an executable, this file does not by itself cause the
00022 //  resulting executable to be covered by the GNU General Public
00023 //  License.  This exception does not however invalidate any other
00024 //  reasons why the executable file might be covered by the GNU General
00025 //  Public License.
00026 //
00027 //  $Id: functional.h,v 1.1 2002/05/30 18:01:37 petter_urkedal Exp $
00028 
00029 
00030 #ifndef MORE_GEN_FUNCTIONAL_H
00031 #define MORE_GEN_FUNCTIONAL_H
00032 
00033 #include <functional>
00034 #include <iterator>
00035 
00036 namespace more {
00037 namespace gen {
00038 
00039   using std::unary_function;
00040   using std::binary_function;
00041   using std::pointer_to_unary_function;
00042   using std::pointer_to_binary_function;
00043   using std::mem_fun_ref_t;
00044   using std::mem_fun1_ref_t;
00045   using std::mem_fun_t;
00046   using std::mem_fun1_t;
00047 
00048 
00049   //  ---   b a s i c   e x t e n s i o n s   for
00050   //        generators, ternary functions, and `bound' member functions ---
00051 
00052   /** \class generator functional.h more/gen/functional.h
00053    *  Convenience base class for a functional taking no arguments. */
00054   template <class Result>
00055     struct generator { typedef Result result_type; };
00056 
00057   /** \class pointer_to_generator functional.h more/gen/functional.h
00058    *  Encapsulation of a pointer to a function taking no arguments. */
00059   template <typename Result>
00060     struct pointer_to_generator : generator<Result>
00061     {
00062         pointer_to_generator(Result (*f_)()) : f(f_) {}
00063         Result operator()() { return f(); }
00064 
00065       private:
00066         Result (*f)();
00067     };
00068 
00069   /** \class ternary_function functional.h more/gen/functional.h
00070    *  Convenience base class for a functional taking three arguments. */
00071   template <class Arg1, class Arg2, class Arg3, class Result>
00072     struct ternary_function
00073     {
00074         typedef Arg1 first_argument_type;
00075         typedef Arg2 second_argument_type;
00076         typedef Arg3 third_argument_type;
00077         typedef Result result_type;
00078     };
00079 
00080   /** \class pointer_to_ternary_function functional.h more/gen/functional.h
00081    *  Encapsulation of a pointer to a ternary function. */
00082   template <typename Arg1, typename Arg2, typename Arg3, typename Res>
00083     struct pointer_to_ternary_function
00084         : ternary_function<Arg1, Arg2, Arg3, Res>
00085     {
00086         pointer_to_ternary_function(Res (*f_)(Arg1, Arg2, Arg3)) : f(f_) {}
00087         Res operator()(Arg1 x1, Arg2 x2, Arg3 x3) const
00088         {
00089             return f(x1, x2, x3);
00090         }
00091 
00092       private:
00093         Res (*f)(Arg1, Arg2, Arg3);
00094     };
00095 
00096   /** \class mem_fun2_t functional.h more/gen/functional.h
00097    *  Encapsulation of a pointer to a member function taking two
00098    *  additional arguments. */
00099   template <typename Res, typename Obj, typename Arg1, typename Arg2>
00100     struct mem_fun2_t
00101         : ternary_function<Obj*, Arg1, Arg2, Res>
00102     {
00103         mem_fun2_t(Res (Obj::*f_)(Arg1, Arg2)) : f(f_) {}
00104         Res operator()(Obj* obj, Arg1 x1, Arg2 x2)
00105         {
00106             return obj->*f(x1, x2);
00107         }
00108 
00109       private:
00110         Res (Obj::*f)(Arg1, Arg2);
00111     };
00112 
00113   //  mem_fun_ref_t and mem_fun1_ref_t in the standard (at least CD2)
00114   //  typedefs result_type to be `T' when the argument to operator()
00115   //  is `T&'.  These definitions fixes the problem.
00116 
00117   /** \class mem_fun_ref_fixed_t functional.h more/gen/functional.h
00118    *  An alternative to std::mem_fun_ref_t. */
00119   template <typename Res, typename Obj>
00120     struct mem_fun_ref_fixed_t
00121         : unary_function<Obj&, Res>
00122     {
00123         mem_fun_ref_fixed_t(Res (Obj::*f_)()) : f(f_) {}
00124         Res operator()(Obj& obj) { return (obj.*f)(); }
00125 
00126       private:
00127         Res (Obj::*f)();
00128     };
00129 
00130   /** \class mem_fun1_ref_fixed_t functional.h more/gen/functional.h
00131    *  An alternative to std::mem_fun1_ref_t. */
00132   template <typename Res, typename Obj, typename Arg>
00133     struct mem_fun1_ref_fixed_t
00134         : binary_function<Obj&, Arg, Res>
00135     {
00136         mem_fun1_ref_fixed_t(Res (Obj::*f_)(Arg)) : f(f_) {}
00137         Res operator()(Obj& obj, Arg x) { return (obj.*f)(x); }
00138 
00139       private:
00140         Res (Obj::*f)(Arg);
00141     };
00142 
00143   /** \class mem_fun2_ref_fixed_t functional.h more/gen/functional.h
00144    *  Encapsulation of a pointer to a member function taking two
00145    *  additional arguments.  The class object argument is a
00146    *  reference. */
00147   template <typename Res, typename Obj, typename Arg1, typename Arg2>
00148     struct mem_fun2_ref_fixed_t
00149         : ternary_function<Obj&, Arg1, Arg2, Res>
00150     {
00151         mem_fun2_ref_fixed_t(Res (Obj::*f_)(Arg1, Arg2)) : f(f_) {}
00152         Res operator()(Obj& obj, Arg1 x1, Arg2 x2)
00153         {
00154             return (obj.*f)(x1, x2);
00155         }
00156 
00157       private:
00158         Res (Obj::*f)(Arg1, Arg2);
00159     };
00160 
00161 
00162   //  Bound member functions
00163 
00164   /** \class bound_mem_fun_ref_t functional.h more/gen/functional.h */
00165   template<typename Res, typename Obj>
00166     struct bound_mem_fun_ref_t : generator<Res>
00167     {
00168         bound_mem_fun_ref_t(Obj& obj_, Res (Obj::*f_)())
00169             : obj(obj_), f(f_) {}
00170         Res operator()() { return (obj.*f)(); }
00171         Res operator()() const { return (obj.*f)(); }
00172       private:
00173         Obj& obj;
00174         Res (Obj::*f)();
00175     };
00176 
00177   /** \class bound_mem_fun1_ref_t functional.h more/gen/functional.h */
00178   template<typename Res, typename Obj, typename Arg>
00179     struct bound_mem_fun1_ref_t : unary_function<Arg, Res>
00180     {
00181         bound_mem_fun1_ref_t(Obj& obj_, Res (Obj::*f_)(Arg))
00182             : obj(obj_), f(f_) {}
00183         Res operator()(Arg x) { return (obj.*f)(x); }
00184         Res operator()(Arg x) const { return (obj.*f)(x); }
00185       private:
00186         Obj& obj;
00187         Res (Obj::*f)(Arg);
00188     };
00189 
00190   /** \class bound_mem_fun2_ref_t functional.h more/gen/functional.h */
00191   template<typename Res, typename Obj, typename Arg1, typename Arg2>
00192     struct bound_mem_fun2_ref_t : binary_function<Arg1, Arg2, Res>
00193     {
00194         bound_mem_fun2_ref_t(Obj& obj_, Res (Obj::*f_)(Arg1, Arg2))
00195             : obj(obj_), f(f_) {}
00196         Res operator()(Arg1 x1, Arg2 x2) { return (obj.*f)(x1, x2); }
00197         Res operator()(Arg1 x1, Arg2 x2) const { return (obj.*f)(x1, x2); }
00198       private:
00199         Obj& obj;
00200         Res (Obj::*f)(Arg1, Arg2);
00201     };
00202 
00203   /** \class bound_mem_fun3_ref_t functional.h more/gen/functional.h */
00204   template< typename Res, typename Obj,
00205             typename Arg1, typename Arg2, typename Arg3 >
00206     struct bound_mem_fun3_ref_t : ternary_function<Arg1, Arg2, Arg3, Res>
00207     {
00208         bound_mem_fun3_ref_t(Obj& obj_, Res (Obj::*f_)(Arg1, Arg2, Arg3))
00209             : obj(obj_), f(f_) {}
00210         Res operator()(Arg1 x1, Arg2 x2, Arg3 x3)
00211             { return (obj.*f)(x1, x2, x3); }
00212         Res operator()(Arg1 x1, Arg2 x2, Arg3 x3) const
00213             { return (obj.*f)(x1, x2, x3); }
00214       private:
00215         Obj& obj;
00216         Res (Obj::*f)(Arg1, Arg2, Arg3);
00217     };
00218 
00219 
00220 
00221   /** \class bound_const_mem_fun_ref_t functional.h more/gen/functional.h */
00222   template<typename Res, typename Obj>
00223     struct bound_const_mem_fun_ref_t : generator<Res>
00224     {
00225         bound_const_mem_fun_ref_t(Obj const& obj_, Res (Obj::*f_)() const)
00226             : obj(obj_), f(f_) {}
00227         Res operator()() const { return (obj.*f)(); }
00228       private:
00229         const Obj& obj;
00230         Res (Obj::*f)() const;
00231     };
00232 
00233   /** \class bound_const_mem_fun1_ref_t functional.h more/gen/functional.h */
00234   template<typename Res, typename Obj, typename Arg>
00235     struct bound_const_mem_fun1_ref_t : unary_function<Arg, Res>
00236     {
00237         bound_const_mem_fun1_ref_t(Obj const& obj_,
00238                                    Res (Obj::*f_)(Arg) const)
00239             : obj(obj_), f(f_) {}
00240         Res operator()(Arg x) const { return (obj.*f)(x); }
00241       private:
00242         const Obj& obj;
00243         Res (Obj::*f)(Arg) const;
00244     };
00245 
00246   /** \class bound_const_mem_fun2_ref_t functional.h more/gen/functional.h */
00247   template<typename Res, typename Obj, typename Arg1, typename Arg2>
00248     struct bound_const_mem_fun2_ref_t : binary_function<Arg1, Arg2, Res>
00249     {
00250         bound_const_mem_fun2_ref_t(Obj const& obj_,
00251                                    Res (Obj::*f_)(Arg1, Arg2) const)
00252             : obj(obj_), f(f_) {}
00253         Res operator()(Arg1 x1, Arg2 x2) const { return (obj.*f)(x1, x2); }
00254       private:
00255         const Obj& obj;
00256         Res (Obj::*f)(Arg1, Arg2) const;
00257     };
00258 
00259   /** \class bound_const_mem_fun3_ref_t functional.h more/gen/functional.h */
00260   template< typename Res, typename Obj,
00261             typename Arg1, typename Arg2, typename Arg3 >
00262     struct bound_const_mem_fun3_ref_t
00263         : ternary_function<Arg1, Arg2, Arg3, Res>
00264     {
00265         bound_const_mem_fun3_ref_t(Obj const& obj_,
00266                                    Res (Obj::*f_)(Arg1, Arg2, Arg3) const)
00267             : obj(obj_), f(f_) {}
00268         Res operator()(Arg1 x1, Arg2 x2, Arg3 x3) const
00269             { return (obj.*f)(x1, x2, x3); }
00270       private:
00271         const Obj& obj;
00272         Res (Obj::*f)(Arg1, Arg2, Arg3) const;
00273     };
00274 
00275 
00276 
00277   //  ---   f u n c t i o n   a d a p t o r s   ---
00278 
00279   template<typename Res>
00280     inline pointer_to_generator<Res>
00281     adapt(Res (*f)()) { return pointer_to_generator<Res>(f); }
00282   template<typename Arg, typename Res>
00283     inline pointer_to_unary_function<Arg, Res>
00284     adapt(Res (*f)(Arg)) { return pointer_to_unary_function<Arg, Res>(f); }
00285   template<typename Arg1, typename Arg2, typename Res>
00286     inline pointer_to_binary_function<Arg1, Arg2, Res>
00287     adapt(Res (*f)(Arg1, Arg2))
00288       { return pointer_to_binary_function<Arg1, Arg2, Res>(f); }
00289   template<typename Arg1, typename Arg2, typename Arg3, typename Res>
00290     inline pointer_to_ternary_function<Arg1, Arg2, Arg3, Res>
00291     adapt(Res (*f)(Arg1, Arg2, Arg3))
00292       { return pointer_to_ternary_function<Arg1, Arg2, Arg3, Res>(f); }
00293 
00294 
00295   template<typename Res, typename Obj>
00296     inline mem_fun_ref_fixed_t<Res, Obj>
00297     adapt(Res (Obj::*f)())
00298       { return mem_fun_ref_fixed_t<Res, Obj>(f); }
00299   template<typename Arg, typename Res, typename Obj>
00300     inline mem_fun1_ref_fixed_t<Res, Obj, Arg>
00301     adapt(Res (Obj::*f)(Arg))
00302       { return mem_fun1_ref_fixed_t<Res, Obj, Arg>(f); }
00303   template<typename Arg1, typename Arg2, typename Res, typename Obj>
00304     inline mem_fun2_ref_fixed_t<Res, Obj, Arg1, Arg2>
00305     adapt(Res (Obj::*f)(Arg1, Arg2))
00306       { return mem_fun2_ref_fixed_t<Res, Obj, Arg1, Arg2>(f); }
00307 
00308   //@{
00309   /** Adapt a member function which takes the \c this pointer as the
00310    *  first argument. */
00311   template<typename Res, typename Obj>
00312     inline mem_fun_t<Res, Obj>
00313     adapt_with_ptr(Res (Obj::*f)())
00314       { return mem_fun_t<Res, Obj>(f); }
00315   template<typename Arg, typename Res, typename Obj>
00316     inline mem_fun1_t<Res, Obj, Arg>
00317     adapt_with_ptr(Res (Obj::*f)(Arg))
00318       { return mem_fun1_t<Res, Obj, Arg>(f); }
00319   template<typename Arg1, typename Arg2, typename Res, typename Obj>
00320     inline mem_fun2_t<Res, Obj, Arg1, Arg2>
00321     adapt_with_ptr(Res (Obj::*f)(Arg1, Arg2))
00322       { return mem_fun2_t<Res, Obj, Arg1, Arg2>(f); }
00323   //@}
00324 
00325   //@{
00326   /** Adapt a member function which takes a reference to \c *this as
00327    *  the first argument. */
00328   template<typename Res, typename Obj>
00329     inline mem_fun_ref_fixed_t<Res, Obj>
00330     adapt_with_ref(Res (Obj::*f)())
00331       { return mem_fun_ref_fixed_t<Res, Obj>(f); }
00332   template<typename Arg, typename Res, typename Obj>
00333     inline mem_fun1_ref_fixed_t<Res, Obj, Arg>
00334     adapt_with_ref(Res (Obj::*f)(Arg))
00335       { return mem_fun1_ref_fixed_t<Res, Obj, Arg>(f); }
00336   template<typename Arg1, typename Arg2, typename Res, typename Obj>
00337     inline mem_fun2_ref_fixed_t<Res, Obj, Arg1, Arg2>
00338     adapt_with_ref(Res (Obj::*f)(Arg1, Arg2))
00339       { return mem_fun2_ref_fixed_t<Res, Obj, Arg1, Arg2>(f); }
00340   //@}
00341 
00342   template<typename Res, typename Obj>
00343     inline bound_mem_fun_ref_t<Res, Obj>
00344     bind_adapt(Obj* obj, Res (Obj::*f)())
00345       { return bound_mem_fun_ref_t<Res, Obj>(*obj, f); }
00346   template<typename Arg, typename Res, typename Obj>
00347     inline bound_mem_fun1_ref_t<Res, Obj, Arg>
00348     bind_adapt(Obj* obj, Res (Obj::*f)(Arg))
00349       { return bound_mem_fun1_ref_t<Res, Obj, Arg>(*obj, f); }
00350   template<typename Arg1, typename Arg2, typename Res, typename Obj>
00351     inline bound_mem_fun2_ref_t<Res, Obj, Arg1, Arg2>
00352     bind_adapt(Obj* obj, Res (Obj::*f)(Arg1, Arg2))
00353       { return bound_mem_fun2_ref_t<Res, Obj, Arg1, Arg2>(*obj, f); }
00354   template< typename Arg1, typename Arg2, typename Arg3, typename Res,
00355             typename Obj >
00356     inline bound_mem_fun3_ref_t<Res, Obj, Arg1, Arg2, Arg3>
00357     bind_adapt(Obj* obj, Res (Obj::*f)(Arg1, Arg2, Arg3))
00358       { return bound_mem_fun3_ref_t<Res, Obj, Arg1, Arg2, Arg3>(*obj, f); }
00359 
00360 
00361   template<typename Res, typename Obj>
00362     inline bound_const_mem_fun_ref_t<Res, Obj>
00363     bind_adapt(Obj const* obj, Res (Obj::*f)() const)
00364       { return bound_const_mem_fun_ref_t<Res, Obj>(*obj, f); }
00365   template<typename Arg, typename Res, typename Obj>
00366     inline bound_const_mem_fun1_ref_t<Res, Obj, Arg>
00367     bind_adapt(Obj const* obj, Res (Obj::*f)(Arg) const)
00368       { return bound_const_mem_fun1_ref_t<Res, Obj, Arg>(*obj, f); }
00369   template<typename Arg1, typename Arg2, typename Res, typename Obj>
00370     inline bound_const_mem_fun2_ref_t<Res, Obj, Arg1, Arg2>
00371     bind_adapt(Obj const* obj, Res (Obj::*f)(Arg1, Arg2) const)
00372       { return bound_const_mem_fun2_ref_t<Res, Obj, Arg1, Arg2>(*obj, f); }
00373   template< typename Arg1, typename Arg2, typename Arg3, typename Res,
00374             typename Obj >
00375     inline bound_const_mem_fun3_ref_t<Res, Obj, Arg1, Arg2, Arg3>
00376     bind_adapt(Obj const* obj, Res (Obj::*f)(Arg1, Arg2, Arg3) const)
00377     {
00378         return bound_const_mem_fun3_ref_t<Res, Obj, Arg1, Arg2, Arg3>(*obj, f);
00379     }
00380 
00381 
00382 
00383   //  ---   p a r t i c u l a r   f u n c t o r s   ---
00384 
00385   /** \class counter functional.h more/gen/functional.h
00386    **  A generator which returns numbers with a given increment. */
00387   template<typename T>
00388     struct counter
00389     {
00390         typedef T result_type;
00391         counter(T init = 0, T step_ = 1) : cur(init), step(step_) {}
00392         T operator()() { T tmp = cur; cur += step; return tmp; }
00393       private:
00394         T cur, step;
00395     };
00396 
00397   /** \class dereferencer functional.h more/gen/functional.h
00398    **  A functional which dereferences an iterator. */
00399   template<typename Iterator>
00400     struct dereferencer
00401         : unary_function< Iterator,
00402                           typename std::iterator_traits<Iterator>::value_type >
00403     {
00404         typename std::iterator_traits<Iterator>::value_type
00405         operator()(Iterator it) { return *it; }
00406     };
00407 
00408   /** \class thrower functional.h more/gen/functional.h
00409    ** A functional with, when called, throws an exception. */
00410   template<typename Exception>
00411     struct thrower : unary_function<Exception, void>
00412     {
00413         void operator()(Exception const& xc) { throw xc; }
00414     };
00415 
00416 
00417 
00418 }} // namespace more::gen
00419 
00420 #endif
00421 

Generated on Sat Sep 7 19:11:12 2002 for more with Doxygen 1.2.13.1. Doxygen 1.2.13.1 is written and copyright 1997-2002 by Dimitri van Heesch.