00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef ThePEG_Selector_H
00010 #define ThePEG_Selector_H
00011
00012
00013 #include "ThePEG/Config/ThePEG.h"
00014 #include <stdexcept>
00015 #include <algorithm>
00016 #include <stdexcept>
00017
00018 namespace ThePEG {
00019
00045 template <typename T, typename WeightType = double>
00046 class Selector {
00047
00048 public:
00049
00051 typedef map<WeightType, T, less<WeightType> > MapType;
00052
00054 typedef typename MapType::const_iterator const_iterator;
00055
00057 typedef typename MapType::iterator iterator;
00058
00060 typedef typename MapType::size_type size_type;
00061
00062 public:
00063
00067 Selector() : theSum(WeightType()) {}
00068
00072 void swap(Selector & s)
00073 {
00074 theMap.swap(s.theMap);
00075 std::swap(theSum, s.theSum);
00076 }
00077
00084 WeightType insert(WeightType d, const T & t) {
00085 typedef typename MapType::value_type value_type;
00086 WeightType newSum = theSum + d;
00087 if ( newSum <= theSum ) return d;
00088 theMap.insert(theMap.end(), value_type((theSum = newSum), t));
00089 return theSum;
00090 }
00091
00097 WeightType reweight(WeightType d, const T & t)
00098 {
00099 erase(t);
00100 return insert(d, t);
00101 }
00102
00109 WeightType erase(const T &);
00110
00115 void replace(const T & oldObject, const T & newObject) {
00116 for ( iterator it = theMap.begin(); it != theMap.end(); ++it )
00117 if ( it->second == oldObject ) it->second = newObject;
00118 }
00119
00131 T & select(double rnd, double * remainder = 0) throw(range_error);
00132
00140 T & operator[](double rnd) throw(range_error) { return select(rnd); }
00141
00153 const T & select(double rnd, double * remainder = 0) const throw(range_error);
00154
00162 const T & operator[](double rnd) const throw(range_error) { return select(rnd); }
00163
00176 template <typename RNDGEN>
00177 T & select(RNDGEN & rnd) throw(range_error) {
00178 double rem = 0.0;
00179 T & t = select(rnd(), &rem);
00180 rnd.push_back(rem);
00181 return t;
00182 }
00183
00196 template <typename RNDGEN>
00197 const T & select(RNDGEN & rnd) const throw(range_error) {
00198 double rem = 0.0;
00199 const T & t = select(rnd(), &rem);
00200 rnd.push_back(rem);
00201 return t;
00202 }
00203
00210 WeightType sum() const { return theSum; }
00211
00218 const_iterator begin() const { return theMap.begin(); }
00219
00224 const_iterator end() const { return theMap.end(); }
00225
00229 bool empty() const { return theMap.empty(); }
00230
00234 size_type size() const { return theMap.size(); }
00235
00239 void clear() { theMap.clear(); theSum = WeightType(); }
00240
00244 template <typename OStream>
00245 void output(OStream &) const;
00246
00250 template <typename IStream>
00251 void input(IStream &);
00252
00253 private:
00254
00258 MapType theMap;
00259
00263 WeightType theSum;
00264
00265 };
00266
00270 template <typename OStream, typename T, typename WeightType>
00271 OStream & operator<<(OStream & os, const Selector<T,WeightType> & s)
00272 {
00273 s.output(os);
00274 return os;
00275 }
00276
00280 template <typename IStream, typename T, typename WeightType>
00281 IStream & operator>>(IStream & is, Selector<T,WeightType> & s)
00282 {
00283 s.input(is);
00284 return is;
00285 }
00286
00287
00288 }
00289
00290 #ifndef ThePEG_TEMPLATES_IN_CC_FILE
00291 #include "Selector.tcc"
00292 #endif
00293
00294 #endif