#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <typeinfo>
#include <type_traits>
#include <tuple>
#include <functional>
#include <string>
#include <list>

#include <iterator>


template <typename T> class VectorList;

template <typename ValueType>
class Iterator : public std::iterator<std::forward_iterator_tag, ValueType>
{
	friend class VectorList<ValueType>;
private:
	Iterator(typename std::list<std::vector<ValueType>>::iterator it);

public:
	Iterator(Iterator const& other);

	Iterator & operator++();
	typename Iterator::reference operator*() const;
	typename Iterator::pointer   operator->() const;
	bool operator!=(Iterator const& other) const;

private:
	typename std::list<std::vector<ValueType>>::iterator data;
};

template <typename ValueType>
Iterator<ValueType>::Iterator(typename std::list<std::vector<ValueType>>::iterator it)
	: data(it)
{

}

template <typename ValueType>
Iterator<ValueType>::Iterator(Iterator const& other)
	: data(other.data)
{

}

template <typename ValueType>
Iterator<ValueType> & Iterator<ValueType>::operator++()
{
	++data;
	return *this;
}

template <typename ValueType>
typename Iterator<ValueType>::reference Iterator<ValueType>::operator*() const
{
	return *data;
}

template <typename ValueType>
typename Iterator<ValueType>::pointer Iterator<ValueType>::operator->() const
{
	return &this->operator*();
}

template <typename ValueType>
bool Iterator<ValueType>::operator!=(Iterator const& other) const
{
	return data != other.data;
}

template<class T>
class VectorList
{
private:
	using VectT = std::vector<T>;
	using ListT = std::list<VectT>;

public:
	using value_type = T;
	using iterator       = Iterator<T>;
	using const_iterator = Iterator<const T>;

	VectorList() = default;
	VectorList(VectorList const &) = default;
	VectorList(VectorList &&) = default;

	VectorList & operator=(VectorList &&) = default;
	VectorList & operator=(VectorList const &) = default;

	template<class It>
	void append(It p, It q);

	bool empty() const { return size() == 0; }

	size_t size() const;

	iterator begin();
	iterator end();


private:
	ListT data_;
};

template <typename T>
template <typename It>
void VectorList<T>::append(It p, It q)
{
	if (p != q)
		data_.push_back(VectT(p, q));
}

template <typename T>
size_t VectorList<T>::size() const
{
	size_t ret = 0;
	for (const VectT& vect : data_)
	{
		ret += vect.size();
	}
	return ret;
}

template <typename T>
typename VectorList<T>::iterator VectorList<T>::begin()
{
	//return Iterator(data_.begin());
}

template <typename T>
typename VectorList<T>::iterator VectorList<T>::end()
{
	//return Iterator(data_.end());
}



int main()
{
	VectorList<int> vl;
	std::vector<int> a = { 1, 2, 3 };
	std::vector<int> b = { 4, 5, 6 };
	vl.append(a.begin(), a.end());
	vl.append(b.begin(), b.end());
	
	for (auto it : vl)
	{
		std::cout << it << ' ';
	}

	return 0;
}