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 00044 00056 template <class EOT> 00057 class eoGenOp : public eoOp<EOT>, public eoUF<eoPopulator<EOT> &, void> 00058 { 00059 public : 00061 eoGenOp(): eoOp<EOT>( eoOp<EOT>::general ) {} 00062 00066 virtual unsigned max_production(void) = 0; 00067 00068 virtual std::string className() const = 0; 00069 void operator()(eoPopulator<EOT>& _pop) 00070 { 00071 _pop.reserve(max_production()); 00072 apply(_pop); 00073 } 00074 00075 00076 protected : 00079 virtual void apply(eoPopulator<EOT>& _pop) = 0; 00080 }; 00081 00082 00084 template <class EOT> 00085 class eoMonGenOp : public eoGenOp<EOT> 00086 { 00087 public: 00088 eoMonGenOp(eoMonOp<EOT>& _op) : op(_op) {} 00089 00090 unsigned max_production(void) { return 1; } 00091 00092 void apply(eoPopulator<EOT>& _it) 00093 { 00094 if (op(*_it)) 00095 (*_it).invalidate(); // look how simple 00096 00097 } 00098 virtual std::string className() const {return op.className();} 00099 private : 00100 eoMonOp<EOT>& op; 00101 }; 00102 00106 template <class EOT> 00107 class eoBinGenOp : public eoGenOp<EOT> 00108 { 00109 public: 00110 eoBinGenOp(eoBinOp<EOT>& _op) : op(_op) {} 00111 00112 unsigned max_production(void) { return 1; } 00113 00117 void apply(eoPopulator<EOT>& _pop) 00118 { 00119 EOT& a = *_pop; 00120 const EOT& b = _pop.select(); 00121 00122 if (op(a, b)) 00123 a.invalidate(); 00124 } 00125 virtual std::string className() const {return op.className();} 00126 00127 private : 00128 eoBinOp<EOT>& op; 00129 }; 00130 00132 template <class EOT> 00133 class eoSelBinGenOp : public eoGenOp<EOT> 00134 { 00135 public: 00136 eoSelBinGenOp(eoBinOp<EOT>& _op, eoSelectOne<EOT>& _sel) : 00137 op(_op), sel(_sel) {} 00138 00139 unsigned max_production(void) { return 1; } 00140 00141 void apply(eoPopulator<EOT>& _pop) 00142 { // _pop.source() gets the original population, an eoVecOp can make use of this as well 00143 if (op(*_pop, sel(_pop.source()))) 00144 (*_pop).invalidate(); 00145 } 00146 virtual std::string className() const {return op.className();} 00147 00148 private : 00149 eoBinOp<EOT>& op; 00150 eoSelectOne<EOT>& sel; 00151 }; 00152 00153 00156 template <class EOT> 00157 class eoQuadGenOp : public eoGenOp<EOT> 00158 { 00159 public: 00160 eoQuadGenOp(eoQuadOp<EOT>& _op) : op(_op) {} 00161 00162 unsigned max_production(void) { return 2; } 00163 00164 void apply(eoPopulator<EOT>& _pop) 00165 { 00166 EOT& a = *_pop; 00167 EOT& b = *++_pop; 00168 00169 00170 if(op(a, b)) 00171 { 00172 a.invalidate(); 00173 b.invalidate(); 00174 } 00175 00176 } 00177 virtual std::string className() const {return op.className();} 00178 00179 private : 00180 eoQuadOp<EOT>& op; 00181 }; 00182 00207 template <class EOT> 00208 eoGenOp<EOT>& wrap_op(eoOp<EOT>& _op, eoFunctorStore& _store) 00209 { 00210 switch(_op.getType()) 00211 { 00212 case eoOp<EOT>::unary : return _store.storeFunctor(new eoMonGenOp<EOT>(static_cast<eoMonOp<EOT>&>(_op))); 00213 case eoOp<EOT>::binary : return _store.storeFunctor(new eoBinGenOp<EOT>(static_cast<eoBinOp<EOT>&>(_op))); 00214 case eoOp<EOT>::quadratic : return _store.storeFunctor(new eoQuadGenOp<EOT>(static_cast<eoQuadOp<EOT>&>(_op))); 00215 case eoOp<EOT>::general : return static_cast<eoGenOp<EOT>&>(_op); 00216 } 00217 00218 assert(false); 00219 return static_cast<eoGenOp<EOT>&>(_op); 00220 } 00221 00222 #endif 00223