#pragma once
#include<utility>
#include<functional>#include"internal/dev_env.hpp"namespaceuni{template<class>structvirtual_combined_map{};template<classMapped,class...Keys>structvirtual_combined_map<Mapped(Keys...)>{usingkey_type=std::tuple<Keys...>;usingmapped_type=Mapped;usingvalue_type=std::pair<key_type,mapped_type>;protected:std::function<Mapped(Keys...)>_f;public:virtual_combined_map()=default;template<classF>explicitvirtual_combined_map(F&&f)noexcept(NO_EXCEPT):_f(f){};inlineconstauto*get_functor()constnoexcept(NO_EXCEPT){returnthis->_f;}inlineauto*get_functor()noexcept(NO_EXCEPT){returnthis->_f;}template<classF>inlineauto&set_functor(F&&f)constnoexcept(NO_EXCEPT){returnthis->_f=f;}inlinemapped_typeoperator()(constKeys&...key)constnoexcept(NO_EXCEPT){returnthis->_f(key...);}inlinemapped_typeoperator[](constkey_type&key)constnoexcept(NO_EXCEPT){returnstd::apply(this->_f,key);}};template<classKey,classMapped>structvirtual_map:virtual_combined_map<Mapped(Key)>{usingkey_type=Key;usingmapped_type=Mapped;usingvalue_type=std::pair<key_type,mapped_type>;usingvirtual_combined_map<mapped_type(key_type)>::virtual_combined_map;inlinemapped_typeoperator[](constkey_type&key)constnoexcept(NO_EXCEPT){returnthis->_f(key);}};};// namesapce uni