<commit_before>/*
 * Copyright 2016, <NAME>
 *
 * This is PUBLIC DOMAIN software so use at your own risk as it comes
 * with no warranties. This code is yours to share, use and modify without
 * any restrictions or obligations.
 *
 * For more information see conwrap/LICENSE or refer refer to http://unlicense.org
 *
 * Author: gimesketvirtadieni at gmail dot com (<NAME>)
 */

#pragma once

#include <future>
#include <functional>
#include <conwrap/HandlerContext.hpp>
#include <conwrap/HandlerWrapper.hpp>


namespace conwrap
{
	template <typename ResourceType, template<typename ResourceType, typename ResultType> class TaskType>
	class ProcessorProxy
	{
		public:
			virtual ResourceType*                getResource() = 0;
			virtual void                         post(HandlerWrapper) = 0;
			virtual HandlerWrapper               wrapHandler(std::function<void()>) = 0;
			virtual HandlerWrapper               wrapHandler(std::function<void()>, bool) = 0;

			// TODO: figure out how to make this method protected
			virtual HandlerContext<ResourceType> createContext() = 0;

			template <typename F>
			auto process(F fun) -> TaskType<ResourceType, decltype(fun())>
			{
				auto promisePtr = std::make_shared<std::promise<decltype(fun())>>();

				// posting a new handler
				this->post(this->wrapHandler([=]
				{
					setPromiseValue(*promisePtr, fun);
				}));

				return TaskType<ResourceType, decltype(fun())>(this, std::shared_future<decltype(fun())>(promisePtr->get_future()));
			}

			template <typename F>
			auto process(F fun) -> TaskType<ResourceType, decltype(fun(createContext()))>
			{
				auto promisePtr = std::make_shared<std::promise<decltype(fun(createContext()))>>();

				// posting a new handler
				this->post(this->wrapHandler([=]
				{
					setPromiseValueWithContext(*promisePtr, fun);
				}));

				return TaskType<ResourceType, decltype(fun(createContext()))>(this, std::shared_future<decltype(fun(createContext()))>(promisePtr->get_future()));
			}

		protected:
			template <typename Fut, typename Fun>
			void setPromiseValue(std::promise<Fut>& p, Fun& f)
			{
				p.set_value(f());
			}

			template <typename Fun>
			void setPromiseValue(std::promise<void>& p, Fun& f)
			{
				f();
				p.set_value();
			}

			template <typename Fut, typename Fun>
			void setPromiseValueWithContext(std::promise<Fut>& p, Fun& f)
			{
				p.set_value(f(createContext()));
			}

			template <typename Fun>
			void setPromiseValueWithContext(std::promise<void>& p, Fun& f)
			{
				f(createContext());
				p.set_value();
			}
	};
}<commit_msg>Minor changes<commit_after>/*
 * Copyright 2016, <NAME>
 *
 * This is PUBLIC DOMAIN software so use at your own risk as it comes
 * with no warranties. This code is yours to share, use and modify without
 * any restrictions or obligations.
 *
 * For more information see conwrap/LICENSE or refer refer to http://unlicense.org
 *
 * Author: gimesketvirtadieni at gmail dot com (<NAME>)
 */

#pragma once

#include <future>
#include <functional>
#include <conwrap/HandlerContext.hpp>
#include <conwrap/HandlerWrapper.hpp>


namespace conwrap
{
	template <typename ResourceType, template<typename ResourceType, typename ResultType> class TaskType>
	class ProcessorProxy
	{
		public:
			// TODO: figure out how to make this method protected
			virtual HandlerContext<ResourceType> createContext() = 0;

			virtual ResourceType* getResource() = 0;

			virtual void post(HandlerWrapper) = 0;

			template <typename F>
			auto process(F fun) -> TaskType<ResourceType, decltype(fun())>
			{
				auto promisePtr = std::make_shared<std::promise<decltype(fun())>>();

				// posting a new handler
				this->post(this->wrapHandler([=]
				{
					setPromiseValue(*promisePtr, fun);
				}));

				return TaskType<ResourceType, decltype(fun())>(this, std::shared_future<decltype(fun())>(promisePtr->get_future()));
			}

			template <typename F>
			auto process(F fun) -> TaskType<ResourceType, decltype(fun(createContext()))>
			{
				auto promisePtr = std::make_shared<std::promise<decltype(fun(createContext()))>>();

				// posting a new handler
				this->post(this->wrapHandler([=]
				{
					setPromiseValueWithContext(*promisePtr, fun);
				}));

				return TaskType<ResourceType, decltype(fun(createContext()))>(this, std::shared_future<decltype(fun(createContext()))>(promisePtr->get_future()));
			}

			virtual HandlerWrapper wrapHandler(std::function<void()>) = 0;

		protected:
			template <typename Fut, typename Fun>
			void setPromiseValue(std::promise<Fut>& p, Fun& f)
			{
				p.set_value(f());
			}

			template <typename Fun>
			void setPromiseValue(std::promise<void>& p, Fun& f)
			{
				f();
				p.set_value();
			}

			template <typename Fut, typename Fun>
			void setPromiseValueWithContext(std::promise<Fut>& p, Fun& f)
			{
				p.set_value(f(createContext()));
			}

			template <typename Fun>
			void setPromiseValueWithContext(std::promise<void>& p, Fun& f)
			{
				f(createContext());
				p.set_value();
			}

			virtual HandlerWrapper wrapHandler(std::function<void()>, bool) = 0;
	};
}
{'fraction_non_alphanumeric': 0.1368836291913215, 'fraction_numerical': 0.0035502958579881655, 'mean_word_length': 4.02079207920792, 'pattern_counts': {'":': 0, '<': 65, '<?xml version=': 0, '>': 81, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6704791', 'n_tokens_mistral': 1852, 'n_tokens_neox': 1535, 'n_words': 387}