ThePEG  1.8.0
Selector.h
1 // -*- C++ -*-
2 //
3 // Selector.h is a part of ThePEG - Toolkit for HEP Event Generation
4 // Copyright (C) 1999-2011 Leif Lonnblad
5 //
6 // ThePEG is licenced under version 2 of the GPL, see COPYING for details.
7 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
8 //
9 #ifndef ThePEG_Selector_H
10 #define ThePEG_Selector_H
11 // This is the declaration of the Selector class.
12 
13 #include "ThePEG/Config/ThePEG.h"
14 #include <stdexcept>
15 #include <algorithm>
16 #include <stdexcept>
17 
18 namespace ThePEG {
19 
45 template <typename T, typename WeightType = double>
46 class Selector {
47 
48 public:
49 
51  typedef map<WeightType, T, less<WeightType> > MapType;
52 
54  typedef typename MapType::const_iterator const_iterator;
55 
57  typedef typename MapType::iterator iterator;
58 
60  typedef typename MapType::size_type size_type;
61 
62 public:
63 
67  Selector() : theSum(WeightType()) {}
68 
72  void swap(Selector & s)
73  {
74  theMap.swap(s.theMap);
76  }
77 
84  WeightType insert(WeightType d, const T & t) {
85  typedef typename MapType::value_type value_type;
86  WeightType newSum = theSum + d;
87  if ( newSum <= theSum ) return d;
88  theMap.insert(theMap.end(), value_type((theSum = newSum), t));
89  return theSum;
90  }
91 
97  WeightType reweight(WeightType d, const T & t)
98  {
99  erase(t);
100  return insert(d, t);
101  }
102 
109  WeightType erase(const T &);
110 
115  void replace(const T & oldObject, const T & newObject) {
116  for ( iterator it = theMap.begin(); it != theMap.end(); ++it )
117  if ( it->second == oldObject ) it->second = newObject;
118  }
119 
131  T & select(double rnd, double * remainder = 0) throw(range_error);
132 
140  T & operator[](double rnd) throw(range_error) { return select(rnd); }
141 
153  const T & select(double rnd, double * remainder = 0) const throw(range_error);
154 
162  const T & operator[](double rnd) const throw(range_error) { return select(rnd); }
163 
176  template <typename RNDGEN>
177  T & select(RNDGEN & rnd) throw(range_error) {
178  double rem = 0.0;
179  T & t = select(rnd(), &rem);
180  rnd.push_back(rem);
181  return t;
182  }
183 
196  template <typename RNDGEN>
197  const T & select(RNDGEN & rnd) const throw(range_error) {
198  double rem = 0.0;
199  const T & t = select(rnd(), &rem);
200  rnd.push_back(rem);
201  return t;
202  }
203 
210  WeightType sum() const { return theSum; }
211 
218  const_iterator begin() const { return theMap.begin(); }
219 
224  const_iterator end() const { return theMap.end(); }
225 
229  bool empty() const { return theMap.empty(); }
230 
234  size_type size() const { return theMap.size(); }
235 
239  void clear() { theMap.clear(); theSum = WeightType(); }
240 
244  template <typename OStream>
245  void output(OStream &) const;
246 
250  template <typename IStream>
251  void input(IStream &);
252 
253 private:
254 
259 
263  WeightType theSum;
264 
265 };
266 
270 template <typename OStream, typename T, typename WeightType>
271 OStream & operator<<(OStream & os, const Selector<T,WeightType> & s)
272 {
273  s.output(os);
274  return os;
275 }
276 
280 template <typename IStream, typename T, typename WeightType>
281 IStream & operator>>(IStream & is, Selector<T,WeightType> & s)
282 {
283  s.input(is);
284  return is;
285 }
286 
287 
288 }
289 
290 #ifndef ThePEG_TEMPLATES_IN_CC_FILE
291 #include "Selector.tcc"
292 #endif
293 
294 #endif /* ThePEG_Selector_H */