#pragma once

#include <vector>

namespace psemek::util
{

	namespace detail
	{

		template <typename T>
		struct default_object_factory
		{
			T operator()()
			{
				return T();
			}
		};

	}

	template <typename T, typename Factory = detail::default_object_factory<T>>
	struct object_pool
	{
		object_pool(Factory factory = Factory())
			: factory_(std::move(factory))
		{}

		T get()
		{
			if (pool_.empty())
				return factory_();

			auto result = std::move(pool_.back());
			pool_.pop_back();
			return result;
		}

		void put(T value)
		{
			pool_.push_back(std::move(value));
		}

	private:
		Factory factory_;
		std::vector<T> pool_;
	};

}
