/*
String const hello("hello");
String const hell = hello[0][4]; // теперь в hell хранится подстрока "hell"
String const ell  = hello[1][4]; // теперь в ell хранится подстрока "ell"


Обратите внимание, что i может равняться j, в этом случае результатом должна быть пустая строка. Гарантируется,
что i никогда не будет больше j, и они не будут выходить за пределы длины строки.

Требования к реализации: При выполнении задания вы можете создавать любые методы/конструкторы или даже структуры/классы,
если они вам нужны. Реализовывать методы, которые уже объявленны в шаблоне, не нужно  они уже реализованы. При выполнении
задания не вводите и не выводите что-либо. Реализовывать функцию main не нужно.
*/

#include <cstddef> // size_t
#include <cstring>

struct String {
	String(const char *str = "");
	String(size_t n, char c);

    String(const String &other);
    String &operator=(const String &other);

	void append(const String &other);
    ~String();

	class Proxy {
	public:
		Proxy(char* const str):str(str), i(0) {		}

		String operator[](size_t j){
			return substr(i, j); 
		}

		String substr(size_t begin, size_t end) {
			char* tmp = static_cast<char*>(memcpy(new char[end - begin + 1], &str[begin], sizeof(char) * (end - begin)));
            tmp[end-begin] = '\0';
			return String(tmp);	
		}

		Proxy& setI(size_t i) {
			this->i = i;
			return *this;
		}

	private:
		size_t i;
		char* const str;
	};

	Proxy operator[] (size_t i) const {
		return Proxy(str).setI(i); 
	}
    
	size_t size;
	char *str;
};