EvolvingObjects
eoGenOp.h
00001 // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
00002 
00003 //-----------------------------------------------------------------------------
00004 // eoGenOp.h
00005 // (c) Maarten Keijzer and Marc Schoenauer, 2001
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
00009     License as published by the Free Software Foundation; either
00010     version 2 of the License, or (at your option) any later version.
00011 
00012     This library is distributed in the hope that it will be useful,
00013     but 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 for more details.
00016 
00017     You should have received a copy of the GNU Lesser General Public
00018     License along with this library; if not, write to the Free Software
00019     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 
00021     Contact: mak@dhi.dk
00022              Marc.Schoenauer@polytechnique.fr
00023  */
00024 //-----------------------------------------------------------------------------
00025 
00026 #ifndef _eoGenOp_H
00027 #define _eoGenOp_H
00028 
00029 #include <eoOp.h>
00030 #include <eoPopulator.h>
00031 #include <eoFunctorStore.h>
00032 #include <assert.h>
00033 
00047 
00059 template <class EOT>
00060 class eoGenOp : public eoOp<EOT>, public eoUF<eoPopulator<EOT> &, void>
00061 {
00062   public :
00064   eoGenOp(): eoOp<EOT>( eoOp<EOT>::general ) {}
00065 
00069     virtual unsigned max_production(void) = 0;
00070 
00071     virtual std::string className() const = 0;
00072 
00073     void operator()(eoPopulator<EOT>& _pop)
00074     {
00075         _pop.reserve( max_production() );
00076         apply(_pop);
00077     }
00078 
00079     //protected :
00082     virtual void apply(eoPopulator<EOT>& _pop) = 0;
00083 };
00089 template <class EOT>
00090 class eoMonGenOp : public eoGenOp<EOT>
00091 {
00092    public:
00093     eoMonGenOp(eoMonOp<EOT>& _op) : op(_op) {}
00094 
00095     unsigned max_production(void) { return 1; }
00096 
00097     void apply(eoPopulator<EOT>& _it)
00098     {
00099       if (op(*_it))
00100         (*_it).invalidate();  // look how simple
00101 
00102     }
00103   virtual std::string className() const {return op.className();}
00104    private :
00105     eoMonOp<EOT>& op;
00106 };
00107 
00111 template <class EOT>
00112 class eoBinGenOp : public eoGenOp<EOT>
00113 {
00114    public:
00115     eoBinGenOp(eoBinOp<EOT>& _op) : op(_op) {}
00116 
00117     unsigned max_production(void) { return 1; }
00118 
00122     void apply(eoPopulator<EOT>& _pop)
00123     {
00124       EOT& a = *_pop;
00125       const EOT& b = _pop.select();
00126 
00127       if (op(a, b))
00128         a.invalidate();
00129     }
00130   virtual std::string className() const {return op.className();}
00131 
00132    private :
00133     eoBinOp<EOT>& op;
00134 };
00135 
00137 template <class EOT>
00138 class eoSelBinGenOp : public eoGenOp<EOT>
00139 {
00140    public:
00141     eoSelBinGenOp(eoBinOp<EOT>& _op, eoSelectOne<EOT>& _sel) :
00142       op(_op), sel(_sel) {}
00143 
00144     unsigned max_production(void) { return 1; }
00145 
00146     void apply(eoPopulator<EOT>& _pop)
00147     { // _pop.source() gets the original population, an eoVecOp can make use of this as well
00148       if (op(*_pop, sel(_pop.source())))
00149         (*_pop).invalidate();
00150     }
00151   virtual std::string className() const {return op.className();}
00152 
00153    private :
00154     eoBinOp<EOT>& op;
00155     eoSelectOne<EOT>& sel;
00156 };
00157 
00158 
00161 template <class EOT>
00162 class eoQuadGenOp : public eoGenOp<EOT>
00163 {
00164    public:
00165     eoQuadGenOp(eoQuadOp<EOT>& _op) : op(_op) {}
00166 
00167     unsigned max_production(void) { return 2; }
00168 
00169     void apply(eoPopulator<EOT>& _pop)
00170     {
00171       EOT& a = *_pop;
00172       EOT& b = *++_pop;
00173 
00174 
00175       if(op(a, b))
00176       {
00177         a.invalidate();
00178         b.invalidate();
00179       }
00180 
00181    }
00182   virtual std::string className() const {return op.className();}
00183 
00184    private :
00185     eoQuadOp<EOT>& op;
00186 };
00187 
00212     template <class EOT>
00213     eoGenOp<EOT>& wrap_op(eoOp<EOT>& _op, eoFunctorStore& _store)
00214     {
00215       switch(_op.getType())
00216       {
00217         case eoOp<EOT>::unary     : return _store.storeFunctor(new eoMonGenOp<EOT>(static_cast<eoMonOp<EOT>&>(_op)));
00218         case eoOp<EOT>::binary    : return _store.storeFunctor(new eoBinGenOp<EOT>(static_cast<eoBinOp<EOT>&>(_op)));
00219         case eoOp<EOT>::quadratic : return _store.storeFunctor(new eoQuadGenOp<EOT>(static_cast<eoQuadOp<EOT>&>(_op)));
00220         case eoOp<EOT>::general   : return static_cast<eoGenOp<EOT>&>(_op);
00221       }
00222 
00223       assert(false);
00224       return static_cast<eoGenOp<EOT>&>(_op);
00225     }
00226 
00227 #endif
00228 
 All Classes Namespaces Files Functions Variables Typedefs Friends