EvolvingObjects
|
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