eoHowMany.h

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 /*
00008    This library is free software; you can redistribute it and/or
00009    modify it under the terms of the GNU Lesser General Public
00010    License as published by the Free Software Foundation; either
00011    version 2 of the License, or (at your option) any later version.
00012 
00013    This library is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016    Lesser General Public License for more details.
00017 
00018    You should have received a copy of the GNU Lesser General Public
00019    License along with this library; if not, write to the Free Software
00020    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021 
00022    Contact: todos@geneura.ugr.es, http://geneura.ugr.es
00023  */
00024 //-----------------------------------------------------------------------------
00025 
00026 #ifndef eoHowMany_h
00027 #define eoHowMany_h
00028 
00067 #include <sstream>
00068 
00069 class eoHowMany : public eoPersistent
00070 {
00071 public:
00076   eoHowMany(double  _rate = 0.0, bool _interpret_as_rate = true):
00077     rate(_rate), combien(0)
00078   {
00079     if (_interpret_as_rate)
00080       {
00081         if (_rate<0)
00082           {
00083             rate = 1.0+_rate;
00084             if (rate < 0)          // was < -1
00085               throw std::logic_error("rate<-1 in eoHowMany!");
00086           }
00087       }
00088     else
00089       {
00090         rate = 0.0;                // just in case, but shoud be unused
00091         combien = int(_rate);      // negative values are allowed here
00092         if (combien != _rate)
00093           std::cerr << "Warning: Number was rounded in eoHowMany";
00094       }
00095   }
00096 
00099   eoHowMany(int _combien) : rate(0.0), combien(_combien) {}
00100 
00103   eoHowMany(unsigned int _combien) : rate(0.0), combien(_combien) {}
00104 
00106   virtual ~eoHowMany() {}
00107 
00114   unsigned int operator()(unsigned int _size)
00115   {
00116     if (combien == 0)
00117       {
00118         return (unsigned int) (rate * _size);
00119       }
00120     if (combien < 0)
00121       {
00122         unsigned int combloc = -combien;
00123         if (_size<combloc)
00124           throw std::runtime_error("Negative result in eoHowMany");
00125         return _size-combloc;
00126       }
00127     return unsigned(combien);
00128   }
00129 
00130   virtual void printOn(std::ostream& _os) const
00131   {
00132     if (combien == 0)
00133       _os << 100*rate << "% ";
00134     else
00135       _os << combien << " ";
00136     return;
00137 
00138   }
00139 
00140   virtual void readFrom(std::istream& _is)
00141    {
00142     std::string value;
00143     _is >> value;
00144     readFrom(value);
00145     return;
00146   }
00147 
00148   void readFrom(std::string _value)
00149   {
00150     // check for %
00151     bool interpret_as_rate = false;   // == no %
00152     size_t pos =  _value.find('%');
00153     if (pos < _value.size())  //  found a %
00154       {
00155         interpret_as_rate = true;
00156         _value.resize(pos);        // get rid of %
00157       }
00158 
00159     std::istringstream is(_value);
00160     is >> rate;
00161     // now store
00162     if (interpret_as_rate)
00163       {
00164         combien = 0;
00165         rate /= 100.0;
00166       }
00167     else
00168       combien = int(rate);         // and rate will not be used
00169 
00170     // minimal check
00171     if ( rate < 0.0 )
00172       throw std::runtime_error("Negative rate read in eoHowMany::readFrom");
00173   }
00174 
00176   eoHowMany operator-()
00177   {
00178     if (!combien)                  // only rate is used
00179       rate = 1.0-rate;
00180     else
00181       combien = -combien;
00182     return (*this);
00183   }
00184 
00185 private :
00186   double rate;
00187   int combien;
00188 };
00189 
00190 
00191 
00192 #endif

Generated on Thu Oct 19 05:06:36 2006 for EO by  doxygen 1.3.9.1