// Wojciech Grześkowiak, Album: 200884, Grupa: G1ISIII
// Opis kontenera Vector.

#include<iostream>
#include<algorithm>
#include<boost/assert.hpp> 
// Ay używac kontenera std:vector należy dołączyć plika nagłówkowy vector.
#include<vector>

using namespace std;

// Szablon funkcji do wypisywania wszystkich elementów
// vectorów niezależnie od tego jakie obiekty trzymają.
template<class T> void printVector(const vector<T> & _v)
{
	// size() zwraca nam liczbę elementów w vektorze.
	for(int i = 0; i < _v.size(); ++i)
		cout << _v[i] << ' ';
	cout << endl;
}

// Głowna funkcja.
int main()
{
	// Tworzymy pusty vector liczb.
	vector<int> liczby1;

	// Dodajemy do kontenera liczby1 9, 8, 7 ...
	// gdzie każda kolejna wrzucana jest na koniec.
	for(int i = 9; i >= 0; --i)
		liczby1.push_back(i);

	// W tym momencie nasz vector wygląda tak:
	// Indeks:  [0|1|2|3|4|5|6|7|8|9]
	// Wartość: [9|8|7|6|5|6|3|2|1|0]
	// Size:	10

	cout << "Liczby1: "; printVector<int>(liczby1);

	// Wyciągnięcie liczby z pod indeksu można zrobic na dwojaki sposób:
	int liczba6_s1 = liczby1[6];		// Tutaj korzystamy z operatora [indeks].
	int liczba6_s2 = liczby1.at(6);		// Tutaj korzystamy z funkcji at(indeks).

	// To są te same liczby.
	BOOST_ASSERT(liczba6_s1 == liczba6_s2);
	
	// Tworzymy nowy vector liczby kopiując elementy z starego.
	vector<int> liczby2(liczby1);

	// Mamy więc identyczny vektor liczb.
	// Zwiekszmy jego rozmiar (size).
	liczby2.resize(liczby2.size() + 5, 33);

	// Funkcja size() zwróciła nam liczbę elementów w vekorze. Była ich tam 10.
	// Zwiekszyliśmy rozmiar do 15, wiec dodano 5 elementów o wartości 
	// przekazanej w drugim parametrze czyli 33. Nasz vector liczby2 wygląda teraz
	// następująco:
	// Indeks:  [0|1|2|3|4|5|6|7|8|9|10|11|12|13|14]
	// Wartość: [9|8|7|6|5|6|3|2|1|0|33|33|33|33|33]
	// Size:	15

	cout << "Liczby2: "; printVector<int>(liczby2);

	// Teraz chcielibyśmy wszystkie lementy z vektora ilczby1 przeniesc
	// do liczby2 i odwrotnie. Za nas zrobi to funkcja swap().
	liczby1.swap(liczby2);

	cout << "Liczby1: "; printVector<int>(liczby1);
	cout << "Liczby2: "; printVector<int>(liczby2);

	// Vektory można także łatwo posrotować, używając algorytmów sortowania.
	// Aby ich użyć należy podać zakres liczb do sortowania, zakres ten
	// podaje się wykorzystując iteratory. start() zwraca iterator wskazujący
	// na początek vektora, end() na koniec.
	sort(liczby1.begin(), liczby1.end());

	// Nasze liczby są już posortowane.
	// Indeks:  [0|1|2|3|4|5|6|7|8|9|10|11|12|13|14]
	// Wartość: [0|1|2|3|4|5|6|7|8|9|33|33|33|33|33]
	cout << "Liczby1: "; printVector<int>(liczby1);

	// Uwórzmy kolejny vector, kopiują cniektore elmenty z poprzedniego.
	// Kopiujemy wszystko oprócz 4 pierwszych i 2 ostatnich elementów,
	// podajac własnie takie iteratory.
	vector<int> liczby3(liczby1.begin() + 4, liczby1.end() - 2);

	// Indeks:  [0|1|2|3|4|5| 6| 7| 8]
	// Wartość: [4|5|6|7|8|9|33|33|33]
	cout << "Liczby3: "; printVector<int>(liczby3);

	// Funkcja pop_back() odrzuca ostatni element.
	// Wywołajmy ja 4 razy.
	for(int i = 0; i < 4; ++i)
		liczby3.pop_back();

	// Indeks:  [0|1|2|3|4]
	// Wartość: [4|5|6|7|8]
	cout << "Liczby3: "; printVector<int>(liczby3);

	// Funkcja push_back(val) wrzuca na koniec wartoc val.
	liczby3.push_back(0);
	liczby3.push_back(1);

	// Indeks:  [0|1|2|3|4|5|6]
	// Wartość: [4|5|6|7|8|0|1]
	cout << "Liczby3: "; printVector<int>(liczby3);

	return 0;
}