//: C07:MultiSet1.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 chování vícenásobné množiny.
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <iterator>
#include <set>
using namespace std;

class X {
  char c; // použito při porovnávání
  int i; // nepoužito při porovnávání
  // Nepotřebuje standardní konstruktor a operator=
  X();
  X& operator=(const X&);
  // Obvykle je potřeba kopírovací konstruktor (ale 
	// spojená verze zde funguje)
public:
  X(char cc, int ii) : c(cc), i(ii) {}
  // Všimněte si, že není potřeba operator==
  friend bool operator<(const X& x, const X& y) {
    return x.c < y.c;
  }
  friend ostream& operator<<(ostream& os, X x) {
    return os << x.c << ":" << x.i;
  }
};

class Xgen {
  static int i;
  // Počet znaků, ze kterých se vybírá:
  enum { SPAN = 6 };
public:
  X operator()() {
    char c = 'A' + rand() % SPAN;
    return X(c, i++);
  }
};

int Xgen::i = 0;

typedef multiset<X> Xmset;
typedef Xmset::const_iterator Xmit;

int main() {
  Xmset mset;
  // Naplnit pomocí X:
  srand(time(0));  // Náhodná čísla
  generate_n(inserter(mset, mset.begin()), 25, Xgen());
  // Inicializovat běžnou množinu z 
	// vícenásobné množiny
  set<X> unique(mset.begin(), mset.end());
  copy(unique.begin(), unique.end(),
    ostream_iterator<X>(cout, " "));
  cout << "\n----" << endl;
  // Projít jedinečné hodnoty:
  for(set<X>::iterator i = unique.begin();
      i != unique.end(); i++) {
    pair<Xmit, Xmit> p = mset.equal_range(*i);
    copy(p.first,p.second, ostream_iterator<X>(cout, " "));
    cout << endl;
  }
} ///:~
