97 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			97 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#pragma once
 | 
						|
#include <functional>
 | 
						|
#include <memory>
 | 
						|
 | 
						|
namespace meta
 | 
						|
{
 | 
						|
	template<typename ... Funcs>
 | 
						|
	class erased_visitor;
 | 
						|
/*
 | 
						|
	template<typename Ret, typename Tuple, typename ...ExtraParams>
 | 
						|
	struct test {};
 | 
						|
 | 
						|
	template<typename Ret, typename OverloadedParam,typename ...OverloadedParams, typename ...ExtraParams>
 | 
						|
	struct test<Ret, std::tuple<OverloadedParam, OverloadedParams...>, ExtraParams...>
 | 
						|
		: std::function<Ret(OverloadedParam,ExtraParams...)>, test<Ret,std::tuple<OverloadedParams...>,ExtraParams...>
 | 
						|
	{
 | 
						|
		using FunctorStorage = std::shared_ptr<void>;
 | 
						|
		using base2 = test<Ret, std::tuple<OverloadedParams...>, ExtraParams...>;
 | 
						|
 | 
						|
		template<typename Visitor, typename = std::enable_if_t<
 | 
						|
			!std::is_same_v<std::decay_t<Visitor>, erased_visitor>>
 | 
						|
			>
 | 
						|
			erased_visitor(Visitor && functor)
 | 
						|
			: std::shared_ptr<void>{ std::make_shared<Visitor>(std::forward<Visitor>(functor)) }
 | 
						|
			, std::function<Rets(OverloadedParam, ExtraParams...)>
 | 
						|
		{
 | 
						|
			std::reference_wrapper<Visitor>(*static_cast<Visitor*>(static_cast<FunctorStorage&>(*this).get()))
 | 
						|
		} , base2{std::forward<Visitor>(functor)}
 | 
						|
		{
 | 
						|
		}
 | 
						|
 | 
						|
			template<typename Visitor, typename = std::enable_if_t<
 | 
						|
				!std::is_same_v<std::decay_t<Visitor>, erased_visitor>>
 | 
						|
				>
 | 
						|
				erased_visitor(const Visitor & functor)
 | 
						|
				: std::shared_ptr<void>{ std::make_shared<Visitor>(functor) }
 | 
						|
				, std::function<Rets(OverloadedParams, ExtraParams...)>
 | 
						|
			{
 | 
						|
				std::reference_wrapper<Visitor>(*static_cast<Visitor*>(static_cast<FunctorStorage&>(*this).get()))
 | 
						|
			} ...
 | 
						|
			{
 | 
						|
			}
 | 
						|
 | 
						|
				using std::function<Rets(OverloadedParams, ExtraParams...)>::operator()...;
 | 
						|
	};
 | 
						|
*/
 | 
						|
	template<typename ...T>
 | 
						|
	struct Inheritor : T...
 | 
						|
	{
 | 
						|
		template<typename...Args>
 | 
						|
		Inheritor(Args&& ... args) : T{args}...
 | 
						|
		{
 | 
						|
 | 
						|
		}
 | 
						|
 | 
						|
		using T::operator()...;
 | 
						|
	};
 | 
						|
 | 
						|
	template<typename Rets, typename ... OverloadedParams, typename ... ExtraParams>
 | 
						|
	class erased_visitor<Rets(OverloadedParams, ExtraParams...) ...>
 | 
						|
		: std::shared_ptr<void>, Inheritor< std::function<Rets(OverloadedParams, ExtraParams...)>...>//, std::function<Rets(OverloadedParams, ExtraParams...)>...
 | 
						|
	{
 | 
						|
	public:
 | 
						|
		using FunctorStorage = std::shared_ptr<void>;
 | 
						|
		using base_t =Inheritor< std::function<Rets(OverloadedParams, ExtraParams...)>...>;
 | 
						|
		
 | 
						|
		template<typename Visitor, typename = std::enable_if_t<
 | 
						|
			!std::is_same_v<std::decay_t<Visitor>, erased_visitor>>
 | 
						|
			>
 | 
						|
		erased_visitor(Visitor&& functor)
 | 
						|
			: std::shared_ptr<void>{ std::make_shared<Visitor>(std::forward<Visitor>(functor)) }
 | 
						|
			, base_t{ std::function<Rets(OverloadedParams, ExtraParams...)>
 | 
						|
			{
 | 
						|
				std::reference_wrapper<Visitor>(*static_cast<Visitor*>(static_cast<FunctorStorage&>(*this).get()))
 | 
						|
			} ... }
 | 
						|
		{
 | 
						|
		}
 | 
						|
 | 
						|
		template<typename Visitor, typename = std::enable_if_t<
 | 
						|
			!std::is_same_v<std::decay_t<Visitor>, erased_visitor>>
 | 
						|
		>
 | 
						|
		erased_visitor(const Visitor& functor)
 | 
						|
			: std::shared_ptr<void>{std::make_shared<Visitor>(functor)}
 | 
						|
			, base_t{ std::function<Rets(OverloadedParams, ExtraParams...)>
 | 
						|
			{
 | 
						|
				std::reference_wrapper<Visitor>(*static_cast<Visitor*>(static_cast<FunctorStorage&>(*this).get()))
 | 
						|
			} ... }
 | 
						|
		{
 | 
						|
		}
 | 
						|
		//template<typename OverloadedParam>
 | 
						|
		//using func_t = Rets(OverloadedParam, ExtraParams...);
 | 
						|
		//template<typename OverloadedParam>
 | 
						|
		//using func2_t = std::function<func_t<OverloadedParam>>;
 | 
						|
		//using func2_t<OverloadedParams>::operator()...;
 | 
						|
		using base_t::operator()...;
 | 
						|
	};
 | 
						|
} |