// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com) // This file is part of the "Nazara Engine - Core module" // For conditions of distribution and use, see copyright notice in Export.hpp #include namespace Nz { namespace Detail { template struct ModuleConfigHasOverride : std::false_type {}; template struct ModuleConfigHasOverride().Override(std::declval()))>> : std::true_type {}; template decltype(auto) OverrideModuleConfig(T&& module, const CommandLineParameters& params) { if constexpr (!std::is_const_v && ModuleConfigHasOverride::value) module.Override(params); return std::forward(module); } template struct Pick { template static decltype(auto) Get(First&& first, Args&&... args) { if constexpr (std::is_same_v>) return std::forward(first); else { NazaraUnused(first); return Get(std::forward(args)...); } } template static decltype(auto) Get(const CommandLineParameters& parameters, First&& first, Args&&... args) { if constexpr (std::is_same_v>) return OverrideModuleConfig(first, parameters); else { NazaraUnused(first); return Get(parameters, std::forward(args)...); } } static auto Get(const CommandLineParameters& parameters) { return OverrideModuleConfig(T{}, parameters); } }; template template ModuleTuple::ModuleTuple(const CommandLineParameters& parameters, ModuleConfig&&... configs) : ModuleTuple(parameters, std::forward(configs)...), ModuleTuple(parameters, std::forward(configs)...) { } template template T& ModuleTuple::Get() { if constexpr (std::is_same_v) return ModuleTuple::template Get(); else return ModuleTuple::template Get(); } template template ModuleTuple::ModuleTuple(const CommandLineParameters& parameters, ModuleConfig&&... configs) : m(Pick::Get(parameters, std::forward(configs)...)) { } template template T& ModuleTuple::Get() { static_assert(std::is_same_v, "module is not in the list"); return m; } } template template Modules::Modules(ModuleConfig&&... configs) : m_modules(CommandLineParameters{}, std::forward(configs)...) { } template template Modules::Modules(const CommandLineParameters& parameters, ModuleConfig&&... configs) : m_modules(parameters, std::forward(configs)...) { } template template T& Modules::Get() { return m_modules.template Get(); } }