From 74ef339cf3d4403cf249f504b6764075552600f6 Mon Sep 17 00:00:00 2001 From: vovatrykoz Date: Tue, 24 Dec 2024 14:00:42 +0100 Subject: [PATCH] use templates for type-safe io setup --- include/Setup.h | 55 ++++--- source/Setup.cpp | 178 +++++----------------- source/executable/main_IndividualPath.cpp | 10 +- source/executable/main_Tasks.cpp | 13 +- 4 files changed, 80 insertions(+), 176 deletions(-) diff --git a/include/Setup.h b/include/Setup.h index 94eb69e..7085b74 100644 --- a/include/Setup.h +++ b/include/Setup.h @@ -13,33 +13,19 @@ namespace setup { using namespace e2e::io; -enum class SupportedLogger { Console, Text, SimplifiedConsole, SimplifiedText }; -enum class SupportedTaskInstanceReader { Console, Text }; -enum class SupportedTaskReader { Console, Text }; - -// Get supported types from string----------------------------------- - -std::optional getSupportedLoggerFromString( - const std::string& loggerStr); - -std::optional getSupportedSimpleLoggerFromString( - const std::string& loggerStr); - -std::optional -getSupportedTaskInstanceReaderFromString(const std::string& readerStr); - -std::optional getSupportedTaskReaderFromString( - const std::string& readerStr); +// Get objects from supported types---------------------------------- -// Get supported types from string----------------------------------- +template +std::unique_ptr makeLogger(Args... args) + requires std::is_base_of_v; -// Get objects from supported types---------------------------------- +template +std::unique_ptr makeTaskInstanceReader(Args... args) + requires std::is_base_of_v; -std::unique_ptr getLoggerFromType(SupportedLogger loggerType); -std::unique_ptr getTaskInstanceReaderFromType( - SupportedTaskInstanceReader readerType); -std::unique_ptr getTaskReaderFromType( - SupportedTaskReader readerType); +template +std::unique_ptr makeTaskReader(Args... args) + requires std::is_base_of_v; // Get objects from supported types---------------------------------- @@ -53,6 +39,27 @@ std::unique_ptr taskReader(const std::string& readerStr); // Get objects from strings types------------------------------------ +template +inline std::unique_ptr makeLogger(Args... args) + requires std::is_base_of_v +{ + return std::make_unique(args...); +} + +template +inline std::unique_ptr makeTaskInstanceReader(Args... args) + requires std::is_base_of_v +{ + return std::make_unique(args...); +} + +template +inline std::unique_ptr makeTaskReader(Args... args) + requires std::is_base_of_v +{ + return std::make_unique(args...); +} + } // namespace setup } // namespace e2e diff --git a/source/Setup.cpp b/source/Setup.cpp index a6f35ad..b387e3a 100644 --- a/source/Setup.cpp +++ b/source/Setup.cpp @@ -15,196 +15,92 @@ using namespace e2e; using namespace e2e::io; -std::optional setup::getSupportedLoggerFromString( - const std::string& loggerStr) { +std::unique_ptr setup::logger(const std::string& loggerStr) { std::string lowercaseLoggerStr; std::transform(loggerStr.begin(), loggerStr.end(), std::back_inserter(lowercaseLoggerStr), [](unsigned char c) { return std::tolower(c); }); if (lowercaseLoggerStr == "console") { - return SupportedLogger::Console; + std::cout << "Logger type: console" << std::endl; + return makeLogger(); } if (lowercaseLoggerStr == "text") { - return SupportedLogger::Text; + std::string outputPath; + std::cout << "Logger type: text" << std::endl; + std::cout << "Enter output path: "; + std::cin >> outputPath; + return makeLogger(outputPath); } - return std::nullopt; + return nullptr; } -std::optional setup::getSupportedSimpleLoggerFromString( - const std::string& loggerStr) { +std::unique_ptr setup::simpleLogger(const std::string& loggerStr) { std::string lowercaseLoggerStr; std::transform(loggerStr.begin(), loggerStr.end(), std::back_inserter(lowercaseLoggerStr), [](unsigned char c) { return std::tolower(c); }); if (lowercaseLoggerStr == "console") { - return SupportedLogger::SimplifiedConsole; + std::cout << "Logger type: console" << std::endl; + return makeLogger(); } if (lowercaseLoggerStr == "text") { - return SupportedLogger::SimplifiedText; + std::string outputPath; + std::cout << "Logger type: text" << std::endl; + std::cout << "Enter output path: "; + std::cin >> outputPath; + return makeLogger(outputPath); } - return std::nullopt; + return nullptr; } -std::optional -setup::getSupportedTaskInstanceReaderFromString(const std::string& readerStr) { +std::unique_ptr setup::taskInstanceReader( + const std::string& readerStr) { std::string lowercaseReaderStr; std::transform(readerStr.begin(), readerStr.end(), std::back_inserter(lowercaseReaderStr), [](unsigned char c) { return std::tolower(c); }); if (lowercaseReaderStr == "console") { - return SupportedTaskInstanceReader::Console; + std::cout << "Reader type: console" << std::endl; + return makeTaskInstanceReader(); } if (lowercaseReaderStr == "text") { - return SupportedTaskInstanceReader::Text; + std::string inputPath; + std::cout << "Reader type: text" << std::endl; + std::cout << "Enter path to input file: "; + std::cin >> inputPath; + return makeTaskInstanceReader(inputPath); } - return std::nullopt; + return nullptr; } -std::optional -setup::getSupportedTaskReaderFromString(const std::string& readerStr) { +std::unique_ptr e2e::setup::taskReader( + const std::string& readerStr) { std::string lowercaseReaderStr; std::transform(readerStr.begin(), readerStr.end(), std::back_inserter(lowercaseReaderStr), [](unsigned char c) { return std::tolower(c); }); if (lowercaseReaderStr == "console") { - return SupportedTaskReader::Console; + std::cout << "Reader type: console" << std::endl; + return makeTaskReader(); } if (lowercaseReaderStr == "text") { - return SupportedTaskReader::Text; - } - - return std::nullopt; -} - -std::unique_ptr setup::getLoggerFromType(SupportedLogger loggerType) { - std::string outputPath; - switch (loggerType) { - case SupportedLogger::Console: - std::cout << "Logger type: console" << std::endl; - return std::make_unique(); - - case SupportedLogger::Text: - std::cout << "Logger type: text" << std::endl; - std::cout << "Enter output path: "; - std::cin >> outputPath; - return std::make_unique(outputPath); - - case SupportedLogger::SimplifiedConsole: - std::cout << "Logger type: console" << std::endl; - return std::make_unique(); - - case SupportedLogger::SimplifiedText: - std::cout << "Logger type: text" << std::endl; - std::cout << "Enter output path: "; - std::cin >> outputPath; - return std::make_unique(outputPath); - - default: - return nullptr; + std::string inputPath; + std::cout << "Reader type: text" << std::endl; + std::cout << "Enter path to input file: "; + std::cin >> inputPath; + return makeTaskReader(inputPath); } return nullptr; } - -std::unique_ptr setup::getTaskInstanceReaderFromType( - SupportedTaskInstanceReader readerType) { - std::string inputPath; - switch (readerType) { - case SupportedTaskInstanceReader::Console: - std::cout << "Reader type: console" << std::endl; - return std::make_unique(); - - case SupportedTaskInstanceReader::Text: - std::cout << "Reader type: text" << std::endl; - std::cout << "Enter path to input file: "; - std::cin >> inputPath; - return std::make_unique(inputPath); - - default: - return nullptr; - } - - return nullptr; -} - -std::unique_ptr e2e::setup::getTaskReaderFromType( - SupportedTaskReader readerType) { - std::string inputPath; - switch (readerType) { - case SupportedTaskReader::Console: - std::cout << "Reader type: console" << std::endl; - return std::make_unique(); - - case SupportedTaskReader::Text: - std::cout << "Reader type: text" << std::endl; - std::cout << "Enter path to input file: "; - std::cin >> inputPath; - return std::make_unique(inputPath); - - default: - return nullptr; - } - - return nullptr; -} - -std::unique_ptr setup::logger(const std::string& loggerStr) { - std::optional loggerType = - setup::getSupportedLoggerFromString(loggerStr); - - if (!loggerType.has_value()) { - std::cerr << "Provided reader is not supported" << std::endl; - return nullptr; - } - - return setup::getLoggerFromType(loggerType.value()); -} - -std::unique_ptr setup::simpleLogger(const std::string& loggerStr) { - std::optional loggerType = - setup::getSupportedSimpleLoggerFromString(loggerStr); - - if (!loggerType.has_value()) { - std::cerr << "Provided reader is not supported" << std::endl; - return nullptr; - } - - return setup::getLoggerFromType(loggerType.value()); -} - -std::unique_ptr setup::taskInstanceReader( - const std::string& readerStr) { - std::optional readerType = - setup::getSupportedTaskInstanceReaderFromString(readerStr); - - if (!readerType.has_value()) { - std::cerr << "Provided reader is not supported" << std::endl; - return nullptr; - } - - return setup::getTaskInstanceReaderFromType(readerType.value()); -} - -std::unique_ptr e2e::setup::taskReader( - const std::string& readerStr) { - std::optional readerType = - setup::getSupportedTaskReaderFromString(readerStr); - - if (!readerType.has_value()) { - std::cerr << "Provided reader is not supported" << std::endl; - return nullptr; - } - - return setup::getTaskReaderFromType(readerType.value()); -} diff --git a/source/executable/main_IndividualPath.cpp b/source/executable/main_IndividualPath.cpp index 0c8c394..fd5d9e5 100644 --- a/source/executable/main_IndividualPath.cpp +++ b/source/executable/main_IndividualPath.cpp @@ -1,5 +1,7 @@ #include #include +#include +#include #include #include @@ -19,16 +21,16 @@ int main(int argc, char* argv[]) { switch (argc) { case 1: // default to console if the user has not provided any input - inputReader = setup::getTaskInstanceReaderFromType( - setup::SupportedTaskInstanceReader::Console); - logger = setup::getLoggerFromType(setup::SupportedLogger::Console); + inputReader = + setup::makeTaskInstanceReader(); + logger = setup::makeLogger(); break; case 2: // if only one parameter is provided, we assume that to be a reader // deafault to console logger inputReader = setup::taskInstanceReader(argv[1]); - logger = setup::getLoggerFromType(setup::SupportedLogger::Console); + logger = setup::makeLogger(); break; case 3: diff --git a/source/executable/main_Tasks.cpp b/source/executable/main_Tasks.cpp index e8fcfa8..db3976b 100644 --- a/source/executable/main_Tasks.cpp +++ b/source/executable/main_Tasks.cpp @@ -1,6 +1,8 @@ #include #include #include +#include +#include #include #include @@ -19,19 +21,16 @@ int main(int argc, char* argv[]) { // setup switch (argc) { case 1: - // default to console if the user has not provided any input - inputReader = - setup::getTaskReaderFromType(setup::SupportedTaskReader::Text); - logger = setup::getLoggerFromType( - setup::SupportedLogger::SimplifiedConsole); + // default to text if the user has not provided any input + inputReader = setup::makeTaskReader(); + logger = setup::makeLogger(); break; case 2: // if only one parameter is provided, we assume that to be a reader // deafault to console logger inputReader = setup::taskReader(argv[1]); - logger = setup::getLoggerFromType( - setup::SupportedLogger::SimplifiedConsole); + logger = setup::makeLogger(); break; case 3: