EvolvingObjects
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 // (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
 All Classes Namespaces Files Functions Variables Typedefs Friends