EvolvingObjects
|
00001 // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- 00002 00003 //----------------------------------------------------------------------------- 00004 // eoHowMany_h.h 00005 // Base class for choosing a number of guys to apply something from a popsize 00006 // (c) Marc Schoenauer, 2000 00007 // (c) Thales group, 2010 (Johann Dréo <johann.dreo@thalesgroup.com>) 00008 00009 /* 00010 This library is free software; you can redistribute it and/or 00011 modify it under the terms of the GNU Lesser General Public 00012 License as published by the Free Software Foundation; either 00013 version 2 of the License, or (at your option) any later version. 00014 00015 This library is distributed in the hope that it will be useful, 00016 but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 Lesser General Public License for more details. 00019 00020 You should have received a copy of the GNU Lesser General Public 00021 License along with this library; if not, write to the Free Software 00022 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00023 00024 Contact: http://eodev.sourceforge.net 00025 00026 */ 00027 //----------------------------------------------------------------------------- 00028 00029 #ifndef eoHowMany_h 00030 #define eoHowMany_h 00031 00032 #include <sstream> 00033 00034 #include <utils/eoLogger.h> 00035 00036 00076 class eoHowMany : public eoPersistent 00077 { 00078 public: 00083 eoHowMany(double _rate = 0.0, bool _interpret_as_rate = true): 00084 rate(_rate), count(0) 00085 { 00086 if (_interpret_as_rate) 00087 { 00088 if (_rate<0) 00089 { 00090 rate = 1.0+_rate; 00091 if (rate < 0) // was < -1 00092 throw std::logic_error("rate<-1 in eoHowMany!"); 00093 } 00094 } 00095 else 00096 { 00097 rate = 0.0; // just in case, but shoud be unused 00098 count = int(_rate); // negative values are allowed here 00099 if (count != _rate) 00100 eo::log << eo::warnings << "Number was rounded in eoHowMany"; 00101 } 00102 } 00103 00106 eoHowMany(int _count) : rate(0.0), count(_count) {} 00107 00110 eoHowMany(unsigned int _count) : rate(0.0), count(_count) {} 00111 00113 virtual ~eoHowMany() {} 00114 00121 unsigned int operator()(unsigned int _size) 00122 { 00123 if (count == 0) 00124 { 00125 unsigned int res = static_cast<unsigned int>( std::ceil( rate * _size ) ); 00126 00127 if( res == 0 ) { 00128 eo::log << eo::warnings << "Call to a eoHowMany instance returns 0 (rate=" << rate << ", size=" << _size << ")" << std::endl; 00129 } 00130 00131 return res; 00132 } 00133 if (count < 0) 00134 { 00135 unsigned int combloc = -count; 00136 if (_size<combloc) 00137 throw std::runtime_error("Negative result in eoHowMany"); 00138 return _size-combloc; 00139 } 00140 return unsigned(count); 00141 } 00142 00143 virtual void printOn(std::ostream& _os) const 00144 { 00145 if (count == 0) 00146 _os << 100*rate << "% "; 00147 else 00148 _os << count << " "; 00149 return; 00150 00151 } 00152 00153 virtual void readFrom(std::istream& _is) 00154 { 00155 std::string value; 00156 _is >> value; 00157 readFrom(value); 00158 return; 00159 } 00160 00161 void readFrom(std::string _value) 00162 { 00163 // check for % 00164 bool interpret_as_rate = false; // == no % 00165 size_t pos = _value.find('%'); 00166 if (pos < _value.size()) // found a % 00167 { 00168 interpret_as_rate = true; 00169 _value.resize(pos); // get rid of % 00170 } 00171 00172 std::istringstream is(_value); 00173 is >> rate; 00174 // now store 00175 if (interpret_as_rate) 00176 { 00177 count = 0; 00178 rate /= 100.0; 00179 } 00180 else 00181 count = int(rate); // and rate will not be used 00182 00183 // minimal check 00184 if ( rate < 0.0 ) 00185 throw std::runtime_error("Negative rate read in eoHowMany::readFrom"); 00186 } 00187 00189 eoHowMany operator-() 00190 { 00191 if (!count) // only rate is used 00192 rate = 1.0-rate; 00193 else 00194 count = -count; 00195 return (*this); 00196 } 00197 00198 private : 00199 double rate; 00200 int count; 00201 }; 00202 00203 00204 00205 #endif