#include <algorithm>
#include <cstdio>
#include <ctime>
#include <iterator>
#include <type_traits>
#include <vector>

#if 1
namespace std
{
	template<class FwdIt, class C>
	back_insert_iterator<C> copy(
		FwdIt begin, FwdIt end, back_insert_iterator<C> it,
		forward_iterator_tag * =
		  static_cast<typename iterator_traits<FwdIt>::iterator_category *>(0))
	{
		struct It : public back_insert_iterator<C>
		{
			using back_insert_iterator<C>::container;
			static C &deref(C &c) { return  c; }
			static C &deref(C *c) { return *c; }
		};
		copy(begin, end, inserter(It::deref(static_cast<It &>(it).container),
					  It::deref(static_cast<It &>(it).container).end()));
		return it;
	}

	template<class FwdIt, class C>
	typename enable_if<  // Only do this if it would be exception-safe!
		has_nothrow_copy_constructor<typename C::value_type>::value &&
		has_nothrow_assign<typename C::value_type>::value,
		insert_iterator<C>
	>::type copy(
		FwdIt const &begin, FwdIt const &end,
		insert_iterator<C> output,
		forward_iterator_tag * =                  // only forward iterators
		  static_cast<typename iterator_traits<FwdIt>::iterator_category *>(0))
	{
		struct It : public insert_iterator<C>
		{
			using insert_iterator<C>::container;  // protected -> public
			using insert_iterator<C>::iter;       // protected -> public
			static C &deref(C &c) { return  c; }
			static C &deref(C *c) { return *c; }
		};
		It &it(static_cast<It &>(output));
		typename C::iterator it_iter_end(It::deref(it.container).end());
		{
			// Convert iterators to offsets
			typename C::size_type const iter_end_off =
				std::distance(It::deref(it.container).begin(), it_iter_end);
			typename iterator_traits<typename C::iterator>::difference_type off
				= std::distance(It::deref(it.container).begin(), it.iter);

			// Resize container
			It::deref(it.container).resize(
				It::deref(it.container).size() +
				static_cast<typename C::size_type>(std::distance(begin, end)));
			
			// Renormalize, in case invalidated
			it.iter = It::deref(it.container).begin();
			std::advance(it.iter, off);
			it_iter_end = It::deref(it.container).begin();
			std::advance(it_iter_end, iter_end_off);
		}
		typename C::iterator result
		  = copy_backward(it.iter, it_iter_end, It::deref(it.container).end());
		copy_backward(begin, end, result);
		return inserter(It::deref(it.container), result);
	}
}
#endif

int main()
{
	std::vector<unsigned char> x;
	x.resize(1000000);
	clock_t begin = clock();
	long long totalMS = 0;
	for (int i = 0; i < 100; i++)
	{
		std::vector<unsigned char> y; y.reserve(x.size());
		std::copy(x.begin(), x.end(), std::back_inserter(y));
	}
	clock_t end = clock();
	printf("%d\n", (int)((end - begin) * 1000 / CLOCKS_PER_SEC));
}