/** File "STLcircles.cpp", by KWR for CSE250, Fall 2009.
    Shows how STL iterators for list and vector etc. go in circles.
 */
#include <iostream>
#include <vector>
#include <list>
#include <set>
//#include <map>
#include <deque>
#include <algorithm>  //for STL binary_search

using namespace std;

/** REQ: ostream& operator<<(ostream& out, const ARG& item);
    OK automatically with string or int etc.
 */
template <class CONT, class ARG>
void circleTest(CONT& cont, string name) {
   typename CONT::iterator itr = cont.begin();
   typename CONT::iterator iend = cont.end();
   size_t sz = cont.size();
   cout << "Going twice around on container " << name << ":" << endl;
   for (int i = 0; i < 2*sz + 2; i++) {
      if (itr == iend) {
         cout << "END ";
         ++itr;
      } else {
         ARG item = *itr++;
         cout << item << " ";
      }
   }
   cout << endl;
}


int main() {
   vector<int> vv;
   deque<int> dd;
   list<int> ll;
   set<int> ss;

   for (int i = 0; i < 7; i++) {
      vv.push_back(i);
      dd.push_back(i);
      ll.push_back(i);
      ss.insert(i);
   }
   circleTest<list<int>,int>(ll, "std::list (doubly-linked list)");
   circleTest<set<int>,int>(ss, "std::set (red-black tree)");
   circleTest<deque<int>,int>(dd, "std::deque (linked list of arrays)");
   circleTest<vector<int>,int>(vv, "std::vector (resizable array)");

   return(0);
}
