#include <cstdlib>
#include <iostream>
#include <string>

using namespace std;

typedef char Znak;
typedef basic_string<Znak> Znaki;
/*W efekcie Znaki, to to samo co string*/

/**
W klasie Haslo przechowujemy haslo zakodowane prostym 
szyfrem przestawieniowym, w którym każdy znak jest zamieniany na inny.
Szyfr jest więc dany na podstawie pewnej permutacji kodów znaków.
*/
template<class Lancuch> class Haslo{
private:
/**zakodowane hasło*/
 Lancuch haslo;  
/**funkcja kodująca pojedynczy znak*/
 Znak* (*koder)(Znak&);
public:    
 Haslo(Znak* (*koder)(Znak&)){haslo=Lancuch(); this->koder=koder;}
 Lancuch kod(Lancuch l);      
 void ustaw(Lancuch haslo){this->haslo=kod(haslo);}
 void wypisz();
};

/**prosta, przykładowa funkcja kodująca*/
Znak* koder1(Znak &z){(z+=255); return &z;}


int main(int argc, char *argv[]){    
    	 cout << "Podaj łancuch znaków do zakodowania" << endl;
        string s;
        cin >> s;
        
	 Znaki l=Znaki();	
        for(unsigned int i=0; i<s.length();i++) l+=s[i];

        Haslo<Znaki> h(koder1);        
        h.ustaw(l);  
	 cout << "kodowanie: " << endl;  
        cout << endl;
        h.wypisz();
        cout << endl;

     return EXIT_SUCCESS;
}

 template <class Lancuch>  
 Lancuch Haslo<Lancuch>::kod(Lancuch l){
    Lancuch pom=Lancuch();
    for (class Lancuch::iterator i=l.begin();i<l.end();i++){
        pom+=*koder(*i);
    }                
    return pom;    
 }
       
  template <class Lancuch> 
  void Haslo<Lancuch>::wypisz(){
      for (class Lancuch::iterator i=haslo.begin();i<haslo.end();i++)
           cout << *i;
 }

