#include <iostream>
using namespace std;

class PogresanIndeks{
};

template <typename T> //class T
class lista {
      T podaci[1000];
      int potroseno;
public:
      lista() : potroseno(0) {}
      void push_back(const T &x) {podaci[potroseno++] = x;} //ToDo
      T pop_back() {return podaci[--potroseno];}
      //insert
      //delete
      T& operator[](int i) {
         if (i>=0 && i<potroseno) return podaci[i];
         throw PogresanIndeks();
      }
      
      struct iterator {
             T *gdje; 
             iterator(T *p) : gdje(p) {}
             T& operator*() {return *gdje;}
             iterator operator+(int i) {
                      //ToDo
                      return iterator(gdje+i);
             }
             iterator operator++() {++gdje; return iterator(gdje);}
             bool operator==(const iterator &i) {return (gdje==i.gdje);}
      };
      iterator begin() {return iterator(podaci);}
      iterator end() {return iterator(podaci+potroseno);}

template <typename U> 
friend ostream& operator<<(ostream&, const lista<U>&);
};

template <typename U> 
ostream& operator<<(ostream& os, const lista<U>& L) {
       for (int i=0; i<L.potroseno; ++i)
           os << L.podaci[i] << ", ";
       return os;
}


int main() {
    lista<int> L;
    L.push_back(3); L.push_back(2); L.push_back(5); L.push_back(1);
    cout << L << endl; 
    cout << L[2] << endl; 
    L[2] = 77; cout << L << endl; 
    
    for (lista<int>::iterator lii = L.begin(); !(lii == L.end()); ++lii )
        cout << (*lii) << ";";
    cout << endl;
    
    lista<int>::iterator lii = L.begin(); 
    lii = lii + 2; *lii = 777; cout << L << endl;
    
    try {
//        cout << L[-2] << endl; 
//        L[55] = 0;
    }
    catch (PogresanIndeks) {
          cerr << "Nedozvoljeni indeks!" << endl;
    }
    
    
}
