#ifndef CTTI_MAP_HPP #define CTTI_MAP_HPP #include namespace ctti { struct default_symbol_mapping_function { constexpr default_symbol_mapping_function() = default; template void operator()(const Source& source, SourceSymbol, Sink& sink, SinkSymbol) const { ctti::set_member_value(sink, ctti::get_member_value(source)); } }; template void map(const Source& source, Sink& sink, const Function& function) { function(source, SourceSymbol(), sink, SinkSymbol()); } template void map(const Source& source, Sink& sink) { ctti::map(source, sink, ctti::default_symbol_mapping_function()); } template struct symbol_mapping { constexpr symbol_mapping(Function function) : function{function} {} Function function; template auto operator()(const Source& source, SourceSymbol, Sink& sink, SinkSymbol) const -> ctti::meta::void_t()(source, SourceSymbol(), sink, SinkSymbol()))> { function(source, SourceSymbol(), sink, SinkSymbol()); } template auto operator()(const Source& source, SourceSymbol, Sink& sink, SinkSymbol) const -> ctti::meta::void_t()(ctti::get_member_value(source), ctti::type_tag>()))> { ctti::set_member_value(sink, function( ctti::get_member_value(source), ctti::type_tag>() )); } }; template constexpr ctti::symbol_mapping> mapping(const Function& function) { return {function}; } template constexpr ctti::symbol_mapping mapping() { return {ctti::default_symbol_mapping_function()}; } template void map(const Source& source, Sink& sink, const ctti::symbol_mapping&... mapping) { [](...){}((map(source, sink, mapping), 0)...); } } #endif // CTTI_MAP_HPP