//: C06:NString.h
// 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.
// Číslovaný řetězec, který uchovává záznam 
// o počtu výskytů slova, které obsahuje.
#ifndef NSTRING_H
#define NSTRING_H
#include <algorithm>
#include <iostream>
#include <string>
#include <utility>
#include <vector>

typedef std::pair<std::string, int> psi;

// Pouze porovná první prvek
bool operator==(const psi& l, const psi& r) {
  return l.first == r.first;
}

class NString {
  std::string s;
  int tentoVyskyt;
  // Uchovává záznam o počtu výskytů:
  typedef std::vector<psi> vp;
  typedef vp::iterator vpit;
  static vp slova;
  void pridatRetezec(const std::string& x) {
    psi p(x, 0);
    vpit it = std::find(slova.begin(), slova.end(), p);
    if(it != slova.end())
      tentoVyskyt = ++it->second;
    else {
      tentoVyskyt = 0;
      slova.push_back(p);
    }
  }
public:
  NString() : tentoVyskyt(0) {}
  NString(const std::string& x) : s(x) { pridatRetezec(x); }
  NString(const char* x) : s(x) { pridatRetezec(x); }
  // Implicitní operator= a kopírovací konstruktor jsou zde OK.
  friend std::ostream& operator<<(
    std::ostream& os, const NString& ns) {
    return os << ns.s << " [" << ns.tentoVyskyt << "]";
  }
 	// Tohle je potřeba pro třídění. Všimněte si, 
	//že se porovnávájí jen řetězce a ne výskyty:
  friend bool
  operator<(const NString& l, const NString& r) {
    return l.s < r.s;
  }
  friend
  bool operator==(const NString& l, const NString& r) {
    return l.s == r.s;
  }
  // Pro třídění s greater<NString>:
  friend bool
  operator>(const NString& l, const NString& r) {
    return l.s > r.s;
  }
  // k přímému získání řetězce:
  operator const std::string&() const { return s; }
};

// Protože NString::vp je šablona a používáme model vkládání, 
// musí se definovat v hlavičkovém souboru:

NString::vp NString::slova;
#endif // NSTRING_H ///:~
