The DejaVU Framework -- hush 3.1

include: professional-program-21-RoundRobin-RoundRobin.h /cygdrive/d/www/media


- [up] [top] - index make include source logic grammar scripts html configure mx slides talks scenes reports projects
<body bgcolor="#FFFFFF" text="#000000">

include 
include 
using std::vector;

//
// class template RoundRobin
//
// Provides simple round-robin semantics for a list of elements.
// Clients add elements to the end of the list with add().
//
// getNext() returns the next element in the list, starting with the first,
// and cycling back to the first when the end of the list is reached.
//
// remove() removes the element matching the argument.
//
template 
<h4 align=right text=red> RoundRobin</h4><hr>
  class RoundRobin
{
 public:
  //
  // Client can give a hint as to the number of expected elements for
  // incrased efficiency.
  //
  RoundRobin(int numExpected = 0);
  ~RoundRobin();

  //
  // Appends elem to the end of the list. May be called
  // between calls to getNext().
  //
  void add(const T& elem);

  //
  // Removes the first (and only the first) element
  // in the list that is equal (with operator==) to elem.
  // May be called between calls to getNext().
  //
  void remove(const T& elem);

  //
  // Returns the next element in the list, starting from 0 and continuously
  // cycling, taking into account elements that are added or removed.
  //
  T& getNext() throw(std::out_of_range);
 protected:
  vector mElems;
  typename std::vector::iterator mCurElem;

 private:
  // prevent assignment and pass-by-reference
  RoundRobin(const RoundRobin& src);
  RoundRobin& operator=(const RoundRobin& rhs);
};
<hr>


template 
RoundRobin::RoundRobin(int numExpected)
{
  // If the client gave a guideline, reserve that much space.
  mElems.reserve(numExpected);

  // Initialize mCurElem even though it isn't used until
  // there's at least one element.
  mCurElem = mElems.begin();
}

template 
RoundRobin::~RoundRobin()
{
  // nothing to do here -- the vector will delete all the elements
}

//
// Always add the new element at the end
//
template 
void RoundRobin::add(const T& elem)
{
  //
  // Even though we add the element at the end,
  // the vector could reallocate and invalidate the iterator.
  // Take advantage of the random access iterator features to save our
  // spot.
  //
  int pos = mCurElem - mElems.begin();

  // add the element
  mElems.push_back(elem);

  // If it's the first element, initialize the iterator to the beginning
  if (mElems.size() == 1) { 
    mCurElem = mElems.begin();
  } else {
    // set it back to our spot
    mCurElem = mElems.begin() + pos;
  }
}

template 
void RoundRobin::remove(const T& elem)
{
  for (typename std::vector::iterator it = mElems.begin(); it != mElems.end(); ++it) {
    if (*it == elem) {
      //
      // Removing an element will invalidate our mCurElem iterator if
      // it refers to an element past the point of the removal.
      // Take advantage of the random access features of the iterator
      // to track the position of the current element after the removal.
      //
      int newPos;

      // If the current iterator is before or at the one we're removing,
      // the new position is the same as before.
      if (mCurElem <= it) {
        newPos = mCurElem - mElems.begin();
      } else {
        // otherwise, it's one less than before
        newPos = mCurElem - mElems.begin() - 1;
      }
      // erase the element (and ignore the return value)
      mElems.erase(it);

      // Now reset our iterator
      mCurElem = mElems.begin() + newPos;

      // If we were pointing to the last element and it was removed,
      // we need to loop back to the first.
      if (mCurElem == mElems.end()) {
        mCurElem = mElems.begin();
      }
      return;
    }
  }
}

template 
T& RoundRobin::getNext()throw(std::out_of_range)
{
  // First, make sure there are any elements.
  if (mElems.empty()) {
    throw std::out_of_range("No elements in the list");
  }

  // retrieve a reference to return
  T& retVal = *mCurElem;

  // Increment the iterator modulo the number of elements
  ++mCurElem;
  if (mCurElem == mElems.end()) {
    mCurElem = mElems.begin();
  }

  // return the reference
  return (retVal);
}
<hr> <style type="text/css"> div.mainnavigate { margin: 20px 2px; /* background-color: #ffffff; */ border: 1px solid black; } </style> <div class=xnavigate> [] <black>readme</black> course(s) preface <black>I</black> 1 2 <black>II</black> 3 4 <black>III</black> 5 6 7 <black>IV</black> 8 9 10 <black>V</black> 11 12 afterthought(s) <black>appendix</black> reference(s) example(s) <black>resource(s)</black> _ </div> <hr>

(C) Æliens 20/2/2008

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author. </div> <script src="http://www.google-analytics.com/urchin.js" type="text/javascript"> </script> <script type="text/javascript"> _uacct = "UA-2780434-1"; urchinTracker(); </script> </body> </html> <hr> <hr> <table cellpadding=10> <tr> <td> <address> Hush Online Technology </address> hush@cs.vu.nl <br>10/19/08 </td><td> </td> <td></td><td></td><td></td><td></td><td></td><td></td><td></td> <td> </td> </tr> </table>