#ifndef INCLUDE_BASE_DYNAMIC_LOADER_IMPLEMENTATION # error Never include this file directly include 'base_dynamic_loader.hpp' #endif #include "util/for_each.hpp" template base_dynamic_loader::base_dynamic_loader(const C enabled_components) : m_enabled_components{ enabled_components } { [&](std::index_sequence) { m_loader_id_lookup = { { std::string{ Loaders::name }, { Is } }... }; }(std::index_sequence_for()); } template std::optional::loader_id_type> base_dynamic_loader::find_loader( std::string_view name ) { const auto it = m_loader_id_lookup.find(name); if (it != m_loader_id_lookup.end()) { return it->second; } return std::nullopt; } template consteval std::optional::loader_id_type> base_dynamic_loader::find_loader_static( std::string_view name ) { constexpr auto invalid_index = std::numeric_limits::max(); auto index = invalid_index; ztu::for_each::indexed_type([&]() { if (name == Loader::name) { index = Index; return true; } return false; }); return index == invalid_index ? std::nullopt : loader_id_type{ index }; } template template::loader_id_type ID> auto& base_dynamic_loader::get_loader() { return std::get(m_loaders); } template template ztu::result base_dynamic_loader::invoke_with_matching_loader( const loader_id_type loader_id, F&& f ) { return std::apply( [&](Loaders&... loaders) { return [&](std::index_sequence) { std::error_code error; const auto found_parser = ( [&](auto& loader, const std::size_t index) { if (loader_id == index) { error = f(loader); return true; } return false; } (loaders, Is) or ... ); if (not found_parser) { error = std::make_error_code(std::errc::invalid_argument); } return error; }(std::index_sequence_for()); }, m_loaders ); }