00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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)
00085 throw std::logic_error("rate<-1 in eoHowMany!");
00086 }
00087 }
00088 else
00089 {
00090 rate = 0.0;
00091 combien = int(_rate);
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
00151 bool interpret_as_rate = false;
00152 size_t pos = _value.find('%');
00153 if (pos < _value.size())
00154 {
00155 interpret_as_rate = true;
00156 _value.resize(pos);
00157 }
00158
00159 std::istringstream is(_value);
00160 is >> rate;
00161
00162 if (interpret_as_rate)
00163 {
00164 combien = 0;
00165 rate /= 100.0;
00166 }
00167 else
00168 combien = int(rate);
00169
00170
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)
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