Skip to content

Commit

Permalink
use templates for type-safe io setup
Browse files Browse the repository at this point in the history
vovatrykoz committed Dec 24, 2024
1 parent ce3a42c commit 74ef339
Showing 4 changed files with 80 additions and 176 deletions.
55 changes: 31 additions & 24 deletions include/Setup.h
Original file line number Diff line number Diff line change
@@ -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<SupportedLogger> getSupportedLoggerFromString(
const std::string& loggerStr);

std::optional<SupportedLogger> getSupportedSimpleLoggerFromString(
const std::string& loggerStr);

std::optional<SupportedTaskInstanceReader>
getSupportedTaskInstanceReaderFromString(const std::string& readerStr);

std::optional<SupportedTaskReader> getSupportedTaskReaderFromString(
const std::string& readerStr);
// Get objects from supported types----------------------------------

// Get supported types from string-----------------------------------
template <typename LoggerType, typename... Args>
std::unique_ptr<ILogger> makeLogger(Args... args)
requires std::is_base_of_v<ILogger, LoggerType>;

// Get objects from supported types----------------------------------
template <typename TaskInstanceReaderType, typename... Args>
std::unique_ptr<ITaskInstanceReader> makeTaskInstanceReader(Args... args)
requires std::is_base_of_v<ITaskInstanceReader, TaskInstanceReaderType>;

std::unique_ptr<ILogger> getLoggerFromType(SupportedLogger loggerType);
std::unique_ptr<ITaskInstanceReader> getTaskInstanceReaderFromType(
SupportedTaskInstanceReader readerType);
std::unique_ptr<ITaskReader> getTaskReaderFromType(
SupportedTaskReader readerType);
template <typename TaskReaderType, typename... Args>
std::unique_ptr<ITaskReader> makeTaskReader(Args... args)
requires std::is_base_of_v<ITaskReader, TaskReaderType>;

// Get objects from supported types----------------------------------

@@ -53,6 +39,27 @@ std::unique_ptr<ITaskReader> taskReader(const std::string& readerStr);

// Get objects from strings types------------------------------------

template <typename LoggerType, typename... Args>
inline std::unique_ptr<ILogger> makeLogger(Args... args)
requires std::is_base_of_v<ILogger, LoggerType>
{
return std::make_unique<LoggerType>(args...);
}

template <typename TaskInstanceReaderType, typename... Args>
inline std::unique_ptr<ITaskInstanceReader> makeTaskInstanceReader(Args... args)
requires std::is_base_of_v<ITaskInstanceReader, TaskInstanceReaderType>
{
return std::make_unique<TaskInstanceReaderType>(args...);
}

template <typename TaskReaderType, typename... Args>
inline std::unique_ptr<ITaskReader> makeTaskReader(Args... args)
requires std::is_base_of_v<ITaskReader, TaskReaderType>
{
return std::make_unique<TaskReaderType>(args...);
}

} // namespace setup
} // namespace e2e

178 changes: 37 additions & 141 deletions source/Setup.cpp
Original file line number Diff line number Diff line change
@@ -15,196 +15,92 @@
using namespace e2e;
using namespace e2e::io;

std::optional<setup::SupportedLogger> setup::getSupportedLoggerFromString(
const std::string& loggerStr) {
std::unique_ptr<ILogger> 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<ConsoleLogger>();
}

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<TextLogger>(outputPath);
}

return std::nullopt;
return nullptr;
}

std::optional<setup::SupportedLogger> setup::getSupportedSimpleLoggerFromString(
const std::string& loggerStr) {
std::unique_ptr<ILogger> 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<SimplifiedConsoleLogger>();
}

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<SimplifiedTextLogger>(outputPath);
}

return std::nullopt;
return nullptr;
}

std::optional<setup::SupportedTaskInstanceReader>
setup::getSupportedTaskInstanceReaderFromString(const std::string& readerStr) {
std::unique_ptr<ITaskInstanceReader> 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<TaskInstanceInputReader>();
}

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<TaskInstanceSimpleTextReader>(inputPath);
}

return std::nullopt;
return nullptr;
}

std::optional<setup::SupportedTaskReader>
setup::getSupportedTaskReaderFromString(const std::string& readerStr) {
std::unique_ptr<ITaskReader> 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<ConsoleTaskReader>();
}

if (lowercaseReaderStr == "text") {
return SupportedTaskReader::Text;
}

return std::nullopt;
}

std::unique_ptr<ILogger> setup::getLoggerFromType(SupportedLogger loggerType) {
std::string outputPath;
switch (loggerType) {
case SupportedLogger::Console:
std::cout << "Logger type: console" << std::endl;
return std::make_unique<ConsoleLogger>();

case SupportedLogger::Text:
std::cout << "Logger type: text" << std::endl;
std::cout << "Enter output path: ";
std::cin >> outputPath;
return std::make_unique<TextLogger>(outputPath);

case SupportedLogger::SimplifiedConsole:
std::cout << "Logger type: console" << std::endl;
return std::make_unique<SimplifiedConsoleLogger>();

case SupportedLogger::SimplifiedText:
std::cout << "Logger type: text" << std::endl;
std::cout << "Enter output path: ";
std::cin >> outputPath;
return std::make_unique<SimplifiedTextLogger>(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<SimpleTextTaskReader>(inputPath);
}

return nullptr;
}

std::unique_ptr<ITaskInstanceReader> setup::getTaskInstanceReaderFromType(
SupportedTaskInstanceReader readerType) {
std::string inputPath;
switch (readerType) {
case SupportedTaskInstanceReader::Console:
std::cout << "Reader type: console" << std::endl;
return std::make_unique<TaskInstanceInputReader>();

case SupportedTaskInstanceReader::Text:
std::cout << "Reader type: text" << std::endl;
std::cout << "Enter path to input file: ";
std::cin >> inputPath;
return std::make_unique<TaskInstanceSimpleTextReader>(inputPath);

default:
return nullptr;
}

return nullptr;
}

std::unique_ptr<ITaskReader> e2e::setup::getTaskReaderFromType(
SupportedTaskReader readerType) {
std::string inputPath;
switch (readerType) {
case SupportedTaskReader::Console:
std::cout << "Reader type: console" << std::endl;
return std::make_unique<ConsoleTaskReader>();

case SupportedTaskReader::Text:
std::cout << "Reader type: text" << std::endl;
std::cout << "Enter path to input file: ";
std::cin >> inputPath;
return std::make_unique<SimpleTextTaskReader>(inputPath);

default:
return nullptr;
}

return nullptr;
}

std::unique_ptr<ILogger> setup::logger(const std::string& loggerStr) {
std::optional<setup::SupportedLogger> 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<ILogger> setup::simpleLogger(const std::string& loggerStr) {
std::optional<setup::SupportedLogger> 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<ITaskInstanceReader> setup::taskInstanceReader(
const std::string& readerStr) {
std::optional<setup::SupportedTaskInstanceReader> 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<ITaskReader> e2e::setup::taskReader(
const std::string& readerStr) {
std::optional<setup::SupportedTaskReader> readerType =
setup::getSupportedTaskReaderFromString(readerStr);

if (!readerType.has_value()) {
std::cerr << "Provided reader is not supported" << std::endl;
return nullptr;
}

return setup::getTaskReaderFromType(readerType.value());
}
10 changes: 6 additions & 4 deletions source/executable/main_IndividualPath.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include <Analysis.h>
#include <Setup.h>
#include <io/logger/ConsoleLogger.h>
#include <io/reader/TaskInstanceInputReader.h>

#include <iostream>
#include <memory>
@@ -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<TaskInstanceInputReader>();
logger = setup::makeLogger<ConsoleLogger>();
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<ConsoleLogger>();
break;

case 3:
13 changes: 6 additions & 7 deletions source/executable/main_Tasks.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include <Analysis.h>
#include <Setup.h>
#include <TaskScheduling.h>
#include <io/logger/SimplifiedConsoleLogger.h>
#include <io/reader/ConsoleTaskReader.h>

#include <iostream>
#include <memory>
@@ -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<ConsoleTaskReader>();
logger = setup::makeLogger<SimplifiedConsoleLogger>();
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<SimplifiedConsoleLogger>();
break;

case 3:

0 comments on commit 74ef339

Please sign in to comment.