callback.h

00001 /*   
00002  *   This file is part of FREESECS.
00003  *
00004  *   FREESECS is free software: you can redistribute it and/or modify
00005  *   it under the terms of the GNU General Public License as published by
00006  *   the Free Software Foundation, either version 3 of the License, or
00007  *   (at your option) any later version.
00008  *
00009  *   FREESECS is distributed in the hope that it will be useful,
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *   GNU General Public License for more details.
00013  *
00014  *   You should have received a copy of the GNU General Public License
00015  *   along with FREESECS, see COPYING.
00016  *   If not, see <http://www.gnu.org/licenses/>.
00017  */
00018 #ifndef _CALLBACK_H
00019 #define _CALLBACK_H
00020 
00021 namespace freesecs
00022 {
00029     class callback_t
00030     {
00031     private:
00032         class callback_base_t
00033         {
00034         public:
00035             virtual ~callback_base_t(){};
00036             virtual callback_base_t *clone() = 0;
00037             virtual int operator ()() = 0;
00038         };
00039 
00040         template<class T>
00041         class callback_impl_t : public callback_base_t
00042         {
00043         public:
00044             typedef int (T::*F)();
00045 
00046             T *p_this;
00047             F  p_func;
00048 
00049             callback_impl_t(T *pthis, F pfunc)
00050             {
00051                 p_this = pthis;
00052                 p_func = pfunc;
00053             }
00054 
00055             callback_impl_t<T> & operator = (const callback_impl_t& cb)
00056             {
00057                 p_this = cb.p_this;
00058                 p_func = cb.p_func;
00059 
00060                 return *this;
00061             }
00062 
00063             callback_impl_t<T> *clone()
00064             {
00065                 return new callback_impl_t<T>(p_this, p_func);
00066             }
00067 
00068             int operator()()
00069             {
00070                 return (p_this->*p_func)();
00071             }
00072         };
00073 
00074             callback_base_t *base;
00075 
00076         public:
00077             virtual int operator()()
00078             {
00079                 if(base)
00080                 {
00081                     return (*base)();
00082                 }
00083                 return -1;
00084             }
00085 
00086             callback_t(const callback_t &cb)
00087             {
00088                 base = cb.base->clone();
00089             }
00090 
00091             virtual ~callback_t()
00092             {
00093                 if(base)
00094                 {
00095                     delete base;
00096                 }
00097             };
00098 
00099             callback_t &operator = (const callback_t& cb)
00100             {
00101                 if(base)
00102                 {
00103                     delete base;
00104                 }
00105                 base = cb.base->clone();
00106                 return *this;
00107             }
00108 
00109             callback_t():base(NULL){}
00110 
00111             template<class T>
00112             callback_t(T *pclass, int (T::*pfunc)())
00113             {
00114                 base = new callback_impl_t<T>(pclass, pfunc);
00115             }
00116 
00117             template<class T>
00118             bool operator == (const callback_t &other)
00119             {
00120                     callback_impl_t<T> *base_impl = (callback_impl_t<T>*)base;
00121                     callback_impl_t<T> *other_base_impl = (callback_impl_t<T>*)other.base;
00122                     return base_impl->p_this == other_base_impl->p_this
00123                         && base_impl->p_func == other_base_impl->p_func;
00124             }
00125     };
00126 
00133     template<class Arg>
00134     class callback_1arg_t
00135     {
00136     private:
00137         class callback_1arg_base_t
00138         {
00139         public:
00140             virtual ~callback_1arg_base_t(){};
00141             virtual callback_1arg_base_t *clone() = 0;
00142             virtual int operator ()(const Arg&) = 0;
00143         };
00144 
00145         template<class T>
00146         class callback_1arg_impl_t : public callback_1arg_base_t
00147         {
00148         public:
00149             typedef int (T::*F)(const Arg&);
00150 
00151             T *p_this;
00152             F  p_func;
00153 
00154             callback_1arg_impl_t(T *pthis, F pfunc)
00155             {
00156                 p_this = pthis;
00157                 p_func = pfunc;
00158             }
00159 
00160             virtual ~callback_1arg_impl_t(){}
00161 
00162             callback_1arg_impl_t<T> & operator = (const callback_1arg_impl_t& cb)
00163             {
00164                 p_this = cb.p_this;
00165                 p_func = cb.p_func;
00166 
00167                 return *this;
00168             }
00169 
00170             callback_1arg_impl_t<T> *clone()
00171             {
00172                 return new callback_1arg_impl_t<T>(p_this, p_func);
00173             }
00174 
00175             int operator()(const Arg &a)
00176             {
00177                 return (p_this->*p_func)(a);
00178             }
00179         };
00180 
00181         callback_1arg_base_t *base;
00182 
00183     public:
00184 
00185         virtual int operator()(const Arg &a)
00186         {
00187             if(base)
00188             {
00189                 return (*base)(a);
00190             }
00191             return -1;
00192         }
00193 
00194         callback_1arg_t(const callback_1arg_t &cb)
00195         {
00196             base = cb.base->clone();
00197         }
00198 
00199         virtual ~callback_1arg_t()
00200         {
00201             if(base)
00202             {
00203                 delete base;
00204             }
00205         }
00206 
00207         callback_1arg_t &operator = (const callback_1arg_t& cb)
00208         {
00209             if(base)
00210             {
00211                 delete base;
00212             }
00213             base = cb.base->clone();
00214             return *this;
00215         }
00216 
00217         callback_1arg_t():base(NULL){}
00218 
00219         template<class T>
00220         callback_1arg_t(T *pclass, int (T::*pfunc)(const Arg&))
00221         {
00222             base = new callback_1arg_impl_t<T>(pclass, pfunc);
00223         }
00224 
00225         template<class T>
00226         bool operator == (const callback_1arg_t &other)
00227         {
00228                 callback_1arg_impl_t<T> *base_impl = (callback_1arg_impl_t<T>*)base;
00229                 callback_1arg_impl_t<T> *other_base_impl = (callback_1arg_impl_t<T>*)other.base;
00230                 return base_impl->p_this == other_base_impl->p_this
00231                     && base_impl->p_func == other_base_impl->p_func;
00232         }
00233     };
00234 
00235 }//namespace
00236 
00237 #endif//_CALLBACK_H

Generated on Fri Oct 3 15:30:01 2008 for FREESECS hsms by  doxygen 1.5.1