2. Розробити програму тестування контейнерного класу за прикладом (дивись
Додаток А)
3. У якості типу вказівника ітераторного класу застосувати програмний код
індивідуального завдання з ЛР№1-2 + з перевантаженими операторами зсуву для
потоків вводу виводу з ЛР№5.
4. У контейнерному класі інкапсулювати ітераторний клас (п.2).
5. Розробити у контейнерному класі методи на наступні дії*****:
- Копіювання змісту масив АТД індивідуального класу (п.2) у зазначений
контейнер/інший тогож типу;
- Додавання нових елементів у зазначене місце контейнеру:
push_back(x) - додавання нового елемента в кінець контйнера,
push_front(x) - додавання нового елементу на початок контейнера,
insert(x, p) - додавання нового елемента X у позицію Р;
- Видалення елемента контейнеру:
pop_back() - видалення останнього елементу;
pop_front() - видалення першого елементу;
erase(p) - видалення елементу в позиції Р.
#include <iostream>
#include <string>
using namespace std;
class Customer {
private:
	string surname;
	float priceBasicTariff;
	float priceSocialTariff;
	int countMonthsTariff;
public:

	Customer() : surname(""), priceBasicTariff(0.0f), priceSocialTariff(0.0f),
		countMonthsTariff(0) {
		cout << "Викликаний конструктор без параметрів." << endl;
	}

	Customer(string s, float pBasic, float pSocial, int months)
		: surname(s), priceBasicTariff(pBasic), priceSocialTariff(pSocial),
		countMonthsTariff(months) {

		cout << "Викликаний конструктор зі списком ініціалізаторів для клієнта " << surname << endl;

	}

	Customer(const Customer& other)
		: surname(other.surname), priceBasicTariff(other.priceBasicTariff),

		priceSocialTariff(other.priceSocialTariff), countMonthsTariff(other.countMonthsTariff) {

		cout << "Викликаний конструктор копіювання для клієнта " << other.surname <<
			endl;
	}

	~Customer() {
		cout << "Ми в деструкторі для клієнта " << surname << endl;
	}

	void setSurname(string s) { surname = s; }
	void setPriceBasicTariff(float p) { priceBasicTariff = p; }
	void setPriceSocialTariff(float p) { priceSocialTariff = p; }
	void setCountMonthsTariff(int m) { countMonthsTariff = m; }

	void printInfo() const {
		cout << "Клієнт: " << surname << endl;
		cout << "Базовий тариф: " << priceBasicTariff << endl;
		cout << "Соціальний тариф: " << priceSocialTariff << endl;
		cout << "Місяці: " << countMonthsTariff << endl;

	}

	const string& getSurname() const { return surname; }
	const float& getPriceBasicTariff() const { return priceBasicTariff; }
	const float& getPriceSocialTariff() const { return priceSocialTariff; }
	const int& getCountMonthsTariff() const { return countMonthsTariff; }
};

#define T Customer
//ітераторний клас 
class iter {
protected:
	T* i; // вказівник на елемент даних
public:
	//конструктор
	iter(T* il) : i(il) { }
	//конструктор копіювання
	iter(const iter& x) : i(x.i) { }
	//перевантажена операція присвоєння ітераторів 
	iter& operator=(const iter& x) {
		i = x.i;
		return *this;
	}
	// перевантажена операція розіменування ітератора 
	T& operator*() const {
		return *i;
	}
	// перевантажена операція префіксного інкременту ітератора 
	iter& operator++() {
		++i;
		return *this;
	}
	// перевантажена операція "не дорівнює"  для порівняння ітераторів
	bool operator!=(const iter& x) const {
		return i != x.i;
	}
	// перевантаженя операцій додавання та віднімання ітераторів
	iter operator-(int a) const {
		return iter(i - a);
	}
	int operator-(const iter& other) const {
		return (i - other.i);
	}
	iter operator+(int a) const {
		return iter(i + a);
	}

//...
//...
};
// клас складу виробів //контейер
class Storage {
	T* p; // вказівник на масив виробів
	int size; // кількість елементів масиву
public:
	// конструктор 
	Storage(int n = 1) {
		p = new T[size = n];
		for (iter i = begin(); i != end(); ++i) *i = T();
	}
	// конструктор копіювання 
	Storage(const Storage& a) {
		p = new T[size = a.size];
		for (iter i = begin(); i != end(); ++i) *i = a.p[i - begin()];
	}

	// деструктор 
	~Storage() { delete[]p; }
	// перевантажена операція присвоєння об'єктів 
	Storage& operator=(const Storage& a) {
		if (this != &a) {
			delete[]p;
			p = new T[size = a.size];
			for (iter i = begin(); i != end(); ++i)
				*i = a.p[i - begin()];
		}
		return *this;
	}
	// перевантажена операція введення з потоку 
	friend istream& operator>>(istream& is, Storage& s) {
		for (iter i = s.begin(); i != s.end(); ++i)
			is >> *i;
		return is;
	}
	// перевантажена операція виведення у потік 
	friend ostream& operator<<(ostream& os, Storage& s) {
		for (iter i = s.begin(); i != s.end(); ++i)
			os << *i << '  ';
		os << endl;
		return os;
	}
	// метод обчислення вартості виробів заданого коду 
	double cost(string code) {
		double v = 0;
		for (iter i = begin(); i != end(); ++i)
			if ((*i).getCode() == code)
				v += (*i).getCount() * (*i).getPrice();
		return v;
	}
	// метод визначення значення ітератора перед масивом 
	iter begin() { return iter(p); }
	// метод визначення значення ітератора поза масивом 
	iter end() { return iter(p + size); }

	/////*****//////
	Storage& push_back(T x) {
		Storage temp = *this;
		delete[]p;
		p = new T[size += 1];
		int j = 0;
		for (iter i = begin(); i != end() - 1; ++i)
			*i = temp.p[i - begin()];
		iter i = end() - 1;
		*i = x;
		return *this;
	}
	Storage& push_front(T x) {
		Storage temp = *this;
		delete[]p;
		p = new T[size += 1];
		for (iter i = begin() + 1; i != end(); ++i)
			*i = temp.p[i - begin() - 1];
		iter i = begin();
		*i = x;
		return *this;
	}
	Storage& insert(T x, int pos) {
		Storage temp = *this;
		delete[]p;
		p = new T[size += 1];
		int j = 0;
		for (iter i = begin(); i != end() - pos; ++i)
		{
			*i = temp.p[j++];
		}
		iter i = begin() + pos;
		*i = x;
		j -= pos - 1;
		for (iter i = begin() + pos + 1;
			i != end(); ++i)
		{
			*i = temp.p[j++];
		}
		return *this;
	}
	Storage& pop_back() {
		Storage temp = *this;
		delete[]p;
		p = new T[size -= 1];
		for (iter i = begin(); i != end(); ++i)
			*i = temp.p[i - begin()];
		return *this;
	}
	Storage& pop_front() {
		Storage temp = *this;
		delete[]p;
		p = new T[size -= 1];
		for (iter i = begin(); i != end(); ++i)
			*i = temp.p[i - begin() + 1];
		return *this;
	}
	Storage& erase(int pos) {
		Storage temp = *this;
		delete[]p;
		p = new T[size -= 1];
		int j = 0;
		for (iter i = begin(); i != end() - pos; ++i)
		{
			*i = temp.p[j++];
		}
		j -= pos - 1;
		for (iter i = begin() + pos; i != end(); ++i)
		{
			*i = temp.p[j++];
		}
		return *this;
	}
};

// головна функція 
void main() {

	//Ініціалізувати масив об'єктів класу за інд.завданням
	//...
	int n;
	cin >> n;
	Storage s(n);
	//Вивести зміст контейнеру
	//...
	//Додати новий елемент в кінець контейнеру
	//...
	//Вивести зміст контейнеру
	//...
	//Додати новий елемент на початок контейнеру
	//...
	//Вивести зміст контейнеру
	//...
	//Додати новий елемент у визначину позицію контейнеру
	//...
	//Вивести зміст контейнеру
	//...
	//Додати ще 2 рази любим з вищезастосованих методів
	//..
	//Вивести зміст контейнеру
	//...
	//Видалити останій елемент контейнеру
	//..
	//Вивести зміст контейнеру
	//...
	//Видалити перший елемент контейнеру
	//..
	//Вивести зміст контейнеру
	//...
	//Видалити елемент контейнеру з визначеної позиції
	//..
	//Вивести зміст контейнеру
	//...
}