#include
#include
#include
using namespace std;template
class RoundRobin{ public: //Client can give a hint as to the number of expected elements for increased efficiency RoundRobin(int numExpected = 0); virtual ~RoundRobin(); //Appends element to the end of the list void add(const T& elem); //Removes the first (and only the first) element //in the list that is equal (with operator==) to elem. void remove(const T& elem); //Returns the next element in the list, starting with the first, //and cycling back to the first when end of the list is //reached, taking into account elements that are added or removed. T& getNext(); protected: std::vector
mElems; typename std::vector
::iterator mCurElem; private: //Prevent assignment and pass-by-value. RoundRobin(const RoundRobin& src); RoundRobin& operator=(const RoundRobin& rhs);};template
RoundRobin
::RoundRobin(int numExpected){ //if the client gave a guideline, reserve that much space. mElems.reserve(numExpected); mCurElem = mElems.begin();}template
RoundRobin
::~RoundRobin(){ //nothing}template
void RoundRobin
::add(const T& elem){ //the vector could reallocate and invalidate the iterator with the push_back call. //take advantage of the random access iterator features to save our spot int pos = mCurElem - mElems.begin(); //add mElems.push_back(elem); //Reset out iterator to make sure it's valid mCurElem = mElems.begin() + pos;}template
void RoundRobin
::remove(const T& elem){ typename std::vector
::iterator it; for (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 int newPos; //if 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); //reset iterator to make sure it's valid 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(){ //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; ++mCurElem; if (mCurElem == mElems.end()){ mCurElem = mElems.begin(); } //return the reference return retVal;}template
RoundRobin
::RoundRobin(const RoundRobin& src){ typename std::vector
::iterator it; for (it = src.mElems.begin(); it != src.mElems.end(); ++it) { mElems.push_back(*it); } int pos = src.mCurElem - src.mElems.begin(); mCurElem = mElems.begin() + pos;}template
RoundRobin
& RoundRobin
::operator=(const RoundRobin& rhs){ typename std::vector
::iterator it; for (it = rhs.mElems.begin(); it != rhs.mElems.end(); ++it) { mElems.push_back(*it); } int pos = rhs.mCurElem - rhs.mElems.begin(); mCurElem = mElems.begin() + pos;}//simple process classclass Process{ public: Process(const string& name) : mName(name) {} void doWorkDuringTimeSlice() { cout<< "Process "<< mName << "performing work during time slice."<
& processes); void scheduleTimeSlice(); void removeProcess(const Process& process); protected: RoundRobin
rr;};Scheduler::Scheduler(const vector
& processes) { /* must be const_iterator when vector is const */ for (vector
::const_iterator iter = processes.begin(); iter != processes.end(); ++iter) { rr.add(*iter); }}void Scheduler::scheduleTimeSlice(){ try{ rr.getNext().doWorkDuringTimeSlice(); } catch ( const std::out_of_range& ) { cerr << "No more processes to schedule."<
processes;//= {Process("1"),Process("2"),Process("3")}; processes.push_back(Process("1")); processes.push_back(Process("2")); processes.push_back(Process("3")); Scheduler sched(processes); for(int i=0;i<4;++i) sched.scheduleTimeSlice(); sched.removeProcess(processes[1]); for(int i=0;i<4;++i) sched.scheduleTimeSlice(); return 0;}