//: C07:BasicSequenceOperations.cpp
// Z knihy "Myslíme v jazyce C++, část 2" od Bruce Eckela a Chucka Allisona.
// (c) 1995-2004 MindView, Inc. Všechna práva vyhrazena.
// Přečtěte si podmínky používání zdrojových kódů umístěné v souboru 
// 'Licence.txt' dodávaném spolu s balíčkem kódu dostupným na www.MindView.net.
// Operace dostupné pro všechny základní sekvenční kontejnery
#include <deque>
#include <iostream>
#include <list>
#include <vector>
using namespace std;

template<typename Kontejner>
void print(Kontejner& c, char* nadpis = "") {
  cout << nadpis << ':' << endl;
  if(c.empty()) {
    cout << "(prázdný)" << endl;
    return;
  }
  typename Kontejner::iterator it;
  for(it = c.begin(); it != c.end(); it++)
    cout << *it << " ";
  cout << endl;
  cout << "size() "      << c.size()
       << " max_size() " << c.max_size()
       << " front() "    << c.front()
       << " back() "     << c.back()
       << endl;
}

template<typename KontejnerInt> void zakladniOperace(char* s) {
  cout << "------- " << s << " -------" << endl;
  typedef KontejnerInt Ci;
  Ci c;
  print(c, "c po standardním konstruktoru");
  Ci c2(10, 1); // 10 prvků, všechny hodnoty 1
  print(c2, "c2 po konstruktoru(10,1)");
  int ia[] = { 1, 3, 5, 7, 9 };
  const int IASZ = sizeof(ia)/sizeof(*ia);
  // Inicializovat pomocí iterátorů begin a end:
  Ci c3(ia, ia + IASZ);
  print(c3, "c3 po konstruktoru(iter,iter)");
  Ci c4(c2); // Kopírovací konstruktor
  print(c4, "c4 po kopírovacím konstruktoru(c2)");
  c = c2; // Operátor přiřazení
  print(c, "c po operator=c2");
  c.assign(10, 2); // 10 prvků, všechny hodnoty 2
  print(c, "c po assign(10, 2)");
  // Assign s iterátory begin a end:
  c.assign(ia, ia + IASZ);
  print(c, "c po assign(iter, iter)");
  cout << "c používající reverzní iterátory:" << endl;
  typename Ci::reverse_iterator rit = c.rbegin();
  while(rit != c.rend())
    cout << *rit++ << " ";
  cout << endl;
  c.resize(4);
  print(c, "c po resize(4)");
  c.push_back(47);
  print(c, "c po push_back(47)");
  c.pop_back();
  print(c, "c po pop_back()");
  typename Ci::iterator it = c.begin();
  ++it; ++it;
  c.insert(it, 74);
  print(c, "c po insert(it, 74)");
  it = c.begin();
  ++it;
  c.insert(it, 3, 96);
  print(c, "c po insert(it, 3, 96)");
  it = c.begin();
  ++it;
  c.insert(it, c3.begin(), c3.end());
  print(c, "c po insert("
    "it, c3.begin(), c3.end())");
  it = c.begin();
  ++it;
  c.erase(it);
  print(c, "c po erase(it)");
  typename Ci::iterator it2 = it = c.begin();
  ++it;
  ++it2; ++it2; ++it2; ++it2; ++it2;
  c.erase(it, it2);
  print(c, "c po erase(it, it2)");
  c.swap(c2);
  print(c, "c po swap(c2)");
  c.clear();
  print(c, "c po clear()");
}

int main() {
  zakladniOperace<vector<int> >("vector");
  zakladniOperace<deque<int> >("deque");
  zakladniOperace<list<int> >("list");
} ///:~
