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

more/gen/multiclosure.h

Go to the documentation of this file.
00001 //  more/multiclosure.h -- provides containers of closures
00002 //  Copyright (C) 1998--2001  Petter Urkedal (petter.urkedal@matfys.lth.se)
00003 
00004 //  This file 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 2 of the License, or
00007 //  (at your option) any later version.
00008 
00009 //  This file 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 this program; if not, write to the Free Software
00016 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 
00018 //  As a special exception, you may use this file as part of a free
00019 //  software library without restriction.  Specifically, if other files
00020 //  instantiate templates or use macros or inline functions from this
00021 //  file, or you compile this file and link it with other files to
00022 //  produce an executable, this file does not by itself cause the
00023 //  resulting executable to be covered by the GNU General Public
00024 //  License.  This exception does not however invalidate any other
00025 //  reasons why the executable file might be covered by the GNU General
00026 //  Public License.
00027 
00028 //  $Id: multiclosure.h,v 1.1 2002/05/30 18:01:37 petter_urkedal Exp $
00029 
00030 
00031 #ifndef MORE_GEN_MULTICLOSURE_H
00032 #define MORE_GEN_MULTICLOSURE_H
00033 
00034 #include <list>
00035 #include <more/gen/closure.h>
00036 #include <more/gen/utility.h>
00037 
00038 namespace more {
00039 namespace gen {
00040 
00041 
00042   //  ---   m u l t i c l o s u r e   ---
00043 
00044   template< typename R,
00045             template<typename> class Container=std::list >
00046     struct generator_multiclosure
00047         : Container< generator_closure<R> >
00048     {
00049         typedef typename Container< generator_closure<R> >::iterator iterator;
00050         void operator()()
00051         {
00052             for (iterator it = begin(); it != end(); ++it) (*it)();
00053         }
00054     };
00055 
00056   template< typename A1, typename R,
00057             template<typename> class Container=std::list >
00058     struct unary_multiclosure
00059         : Container< unary_closure<A1, R> >
00060     {
00061         typedef typename Container< unary_closure<A1, R> >::iterator iterator;
00062         void operator()(A1 x1)
00063         {
00064             for (iterator it = begin(); it != end(); ++it) (*it)(x1);
00065         }
00066     };
00067 
00068   template< typename A1, typename A2, typename R,
00069             template<typename> class Container=std::list >
00070     struct binary_multiclosure
00071         : Container< binary_closure<A1, A2, R> >
00072     {
00073         typedef typename Container< binary_closure<A1, A2, R> >::iterator
00074                 iterator;
00075         void operator()(A1 x1, A2 x2)
00076         {
00077             for(iterator it = begin(); it != end(); ++it) (*it)(x1, x2);
00078         }
00079     };
00080 
00081   template< typename A1, typename A2, typename A3, typename R,
00082             template<typename> class Container=std::list >
00083     struct ternary_multiclosure
00084         : Container< ternary_closure<A1, A2, A3, R> >
00085     {
00086         typedef typename Container< ternary_closure<A1, A2, A3, R> >::iterator
00087                 iterator;
00088         void operator()(A1 x1, A2 x2, A3 x3)
00089         {
00090             for(iterator it = begin(); it != end(); ++it) (*it)(x1, x2, x3);
00091         }
00092     };
00093 
00094 
00095 
00096   //  ---   c o n n e c t i o n   ---
00097 
00098   ///\if bits
00099   namespace bits {
00100 
00101     struct connection_base : handle_data
00102     {
00103         virtual void enable() = 0;
00104         virtual void disable() = 0;
00105         virtual bool is_enabled() const = 0;
00106         virtual ~connection_base() {};
00107     };
00108 
00109     template<typename S, typename F>
00110       struct connection_der : connection_base
00111       {
00112           typedef typename S::iterator iterator;
00113 
00114           connection_der(S& s, const F& f)
00115               : slot(s), function(f), it(s.end()) { enable(); }
00116 
00117           virtual void enable()
00118           {
00119               if(it == slot.end())
00120                   it = slot.insert(slot.end(), function);
00121           }
00122           virtual void disable()
00123           {
00124               if(it != slot.end()) {
00125                   slot.erase(it);    // obs: only list supported
00126                   it = slot.end();
00127               }
00128           }
00129           virtual bool is_enabled() const { return it != slot.end(); }
00130           virtual ~connection_der() { disable(); }
00131 
00132         private:
00133           S& slot;
00134           F function;
00135           iterator it;
00136       };
00137 
00138     template<typename S, typename F>
00139       inline connection_base*
00140       new_connection(S& s, const F& f)
00141       {
00142           return new connection_der<S, F>(s, f);
00143       }
00144 
00145   } // bits
00146   ///\endif
00147 
00148   struct connection
00149   {
00150       void enable() { cc.data()->enable(); }
00151       void disable() { cc.data()->disable(); }
00152       bool is_enabled() const { return cc.data()->is_enabled(); }
00153 
00154       ~connection() {} // if(ic.is_unique()) delete cc; }
00155 
00156       template< typename MultiClosure, typename Function >
00157         connection(MultiClosure& slot, Function f)
00158             : cc(new bits::connection_der<MultiClosure, Function>(slot, f)) {}
00159 
00160 #if 0
00161       template< typename Res, template<typename> class C >
00162         connection(generator_multiclosure<Res, C>& slot, Res (*f)())
00163             : cc(bits::new_connection(slot, generator_closure<Res>(adapt(f))))
00164         {}
00165 
00166       template< typename Arg, typename Res, template<typename> class C >
00167         connection(unary_multiclosure<Arg, Res, C>& slot, Res (*f)(Arg))
00168 //      : cc(bits::new_connection(slot, unary_closure<Arg, Res>(adapt(f)))) {}
00169         {
00170             unary_closure<Arg, Res> vf(adapt(f));
00171             typedef bits::connection_der< unary_multiclosure<Arg, Res, C>,
00172                                           unary_closure<Arg, Res> >
00173                 cnn_type;
00174             cc = new cnn_type(slot, f);
00175         }
00176 
00177       template< typename Arg1, typename Arg2, typename Res,
00178                 template<typename> class C >
00179         connection(binary_multiclosure<Arg1, Arg2, Res, C>& slot,
00180                    Res (*f)(Arg1, Arg2))
00181             : cc(bits::new_connection(slot,
00182                                       binary_closure<Arg1, Arg2, Res>
00183                                       (adapt(f)))) {}
00184 
00185       template< typename Arg1, typename Arg2, typename Arg3, typename Res,
00186                 template<typename> class C >
00187         connection(ternary_multiclosure<Arg1, Arg2, Arg3, Res, C>& slot,
00188                    Res (*f)(Arg1, Arg2, Arg3))
00189             : cc(bits::new_connection(slot,
00190                                       ternary_closure<Arg1, Arg2, Arg3, Res>
00191                                       (adapt(f)))) {}
00192 
00193       template< typename Obj, typename Res,
00194                 template<typename> class C >
00195         connection(unary_multiclosure<Obj&, Res, C>& slot,
00196                    Res (Obj::*f)())
00197             : cc(bits::new_connection(slot, unary_closure<Obj&, Res>
00198                                       (adapt(f)))) {}
00199 
00200       template< typename Obj, typename Arg, typename Res,
00201                 template<typename> class C >
00202         connection(binary_multiclosure<Obj&, Arg, Res, C>& slot,
00203                    Res (Obj::*f)(Arg))
00204             : cc(bits::new_connection(slot,
00205                                       binary_closure<Obj&, Arg, Res>
00206                                       (adapt(f)))) {}
00207 
00208       template< typename Obj, typename Arg1, typename Arg2, typename Res,
00209                 template<typename> class C >
00210         connection(ternary_multiclosure<Obj&, Arg1, Arg2, Res, C>& slot,
00211                    Res (Obj::*f)(Arg1, Arg2))
00212             : cc(bits::new_connection(slot,
00213                                       ternary_closure<Obj&, Arg1, Arg2, Res>
00214                                       (adapt(f)))) {}
00215 
00216       template< typename Res, typename Obj, template<typename> class C >
00217         connection(generator_multiclosure<Res, C>& slot,
00218                    Obj& obj, Res (Obj::*f)())
00219             : cc(bits::new_connection(slot,
00220                                       generator_closure<Res>
00221                                       (adapt(obj, f)))) {}
00222 
00223       template< typename Res, typename Arg, typename Obj,
00224                 template<typename> class C >
00225         connection(unary_multiclosure<Arg, Res, C>& slot,
00226                    Obj& obj, Res (Obj::*f)(Arg))
00227             : cc(bits::new_connection(slot,
00228                                       unary_closure<Arg, Res>
00229                                       (adapt(obj, f)))) {}
00230 
00231       template< typename Res, typename Arg1, typename Arg2, typename Obj,
00232                 template<typename> class C >
00233         connection(binary_multiclosure<Arg1, Arg2, Res, C>& slot,
00234                    Obj& obj, Res (Obj::*f)(Arg1, Arg2))
00235             : cc(bits::new_connection(slot,
00236                                       binary_closure<Arg1, Arg2, Res>
00237                                       (adapt(obj, f)))) {}
00238 
00239       template< typename Res, typename Arg1, typename Arg2, typename Arg3,
00240                 typename Obj, template<typename> class C >
00241         connection(ternary_multiclosure<Arg1, Arg2, Arg3, Res, C>& slot,
00242                    Obj& obj, Res (Obj::*f)(Arg1, Arg2, Arg3))
00243             : cc(bits::new_connection(slot,
00244                                       ternary_closure<Arg1, Arg2, Arg3, Res>
00245                                       (adapt(obj, f)))) {}
00246 #endif
00247 
00248     private:
00249       instance_counter ic;
00250       handle<bits::connection_base> cc;
00251   };
00252 
00253 }} // namespace more::gen
00254 
00255 #endif

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