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()...;
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
								}
							 |