//: C06:Manipulations.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.
// Ukazuje základní manipulace
//{L} Generators
// NString
#include <vector>
#include <string>
#include <algorithm>
#include "PrintSequence.h"
#include "NString.h"
#include "Generators.h"
using namespace std;

int main() {
  vector<int> v1(10);
  // Jednoduché počítání:
  generate(v1.begin(), v1.end(), SkipGen());
  print(v1.begin(), v1.end(), "v1", " ");
  vector<int> v2(v1.size());
  copy_backward(v1.begin(), v1.end(), v2.end());
  print(v2.begin(), v2.end(), "copy_backward", " ");
  reverse_copy(v1.begin(), v1.end(), v2.begin());
  print(v2.begin(), v2.end(), "reverse_copy", " ");
  reverse(v1.begin(), v1.end());
  print(v1.begin(), v1.end(), "reverse", " ");
  int half = v1.size() / 2;
  // Rozsahy musí být přesně stejné:
  swap_ranges(v1.begin(), v1.begin() + half,
    v1.begin() + half);
  print(v1.begin(), v1.end(), "swap_ranges", " ");
  // Začít s novou sekvencí:
  generate(v1.begin(), v1.end(), SkipGen());
  print(v1.begin(), v1.end(), "v1", " ");
  int third = v1.size() / 3;
  for(int i = 0; i < 10; i++) {
    rotate(v1.begin(), v1.begin() + third, v1.end());
    print(v1.begin(), v1.end(), "rotate", " ");
  }
  cout << "Druhý příklad na rotate:" << endl;
  char c[] = "aabbccddeeffgghhiijj";
  const char CSZ = strlen(c);
  for(int i = 0; i < 10; i++) {
    rotate(c, c + 2, c + CSZ);
    print(c, c + CSZ, "", "");
  }
  cout << "Všech n! permutací sekvence abcd:" << endl;
  int nf = 4 * 3 * 2 * 1;
  char p[] = "abcd";
  for(int i = 0; i < nf; i++) {
    next_permutation(p, p + 4);
    print(p, p + 4, "", "");
  }
  cout << "Použití prev_permutation:" << endl;
  for(int i = 0; i < nf; i++) {
    prev_permutation(p, p + 4);
    print(p, p + 4, "", "");
  }
  cout << "Použití random_shuffle na slovo:" << endl;
  string s("Ahoj");
  cout << s << endl;
  for(int i = 0; i < 5; i++) {
    random_shuffle(s.begin(), s.end());
    cout << s << endl;
  }
  NString sa[] = { "a", "b", "c", "d", "a", "b",
    "c", "d", "a", "b", "c", "d", "a", "b", "c"};
  const int SASZ = sizeof sa / sizeof *sa;
  vector<NString> ns(sa, sa + SASZ);
  print(ns.begin(), ns.end(), "ns", " ");
  vector<NString>::iterator it =
    partition(ns.begin(), ns.end(),
      bind2nd(greater<NString>(), "b"));
  cout << "Oddělovací bod: " << *it << endl;
  print(ns.begin(), ns.end(), "", " ");
  // Znovu nahraný vektor:
  copy(sa, sa + SASZ, ns.begin());
  it = stable_partition(ns.begin(), ns.end(),
    bind2nd(greater<NString>(), "b"));
  cout << "Stabilní oddělení" << endl;
  cout << "Oddělovací bod: " << *it << endl;
  print(ns.begin(), ns.end(), "", " ");
} ///:~
