diff --git a/components/CLParser/include/Modelec/CLParser.h b/components/CLParser/include/Modelec/CLParser.h index a10edf7..5761ce0 100644 --- a/components/CLParser/include/Modelec/CLParser.h +++ b/components/CLParser/include/Modelec/CLParser.h @@ -7,6 +7,8 @@ #include #include +#include + class CLParser { public: @@ -16,42 +18,25 @@ public: [[nodiscard]] bool hasOption(const std::string& option) const; - [[nodiscard]] std::optional getOption(const std::string& option) const; - - [[nodiscard]] std::string getOption(const std::string& option, const std::string& defaultValue) const; - template - [[nodiscard]] std::enable_if_t, T> getOption(const std::string& option, T defaultValue) const { + [[nodiscard]] T getOption(const std::string& option, T defaultValue) const { if (!hasOption(option)) { return defaultValue; } - T value; - std::istringstream iss(_options.at(option)); - iss >> value; - - if (iss.fail() || !iss.eof()) { - std::cout << "Failed convert" << std::endl; - return defaultValue; - } - + T value = T(); + parseString(_options.at(option), ParameterTypeTraits::type, static_cast(&value)); return value; } template - [[nodiscard]] std::optional, T>> getOption(const std::string& option) const { + [[nodiscard]] std::optional getOption(const std::string& option) const { if (!hasOption(option)) { return std::nullopt; } - T value; - std::istringstream iss(_options.at(option)); - iss >> value; - - if (iss.fail() || !iss.eof()) { - return std::nullopt; - } - + T value = T(); + parseString(_options.at(option), ParameterTypeTraits::type, static_cast(&value)); return value; } @@ -60,19 +45,13 @@ public: [[nodiscard]] std::string getPositionalArgument(int index) const; template - [[nodiscard]] std::enable_if_t, T> getPositionalArgument(int index) const { + [[nodiscard]] T getPositionalArgument(int index) const { if (!hasPositionalArgument(index)) { return T(); } - T value; - std::istringstream iss(_argv[index]); - iss >> value; - - if (iss.fail() || !iss.eof()) { - return T(); - } - + T value = T(); + parseString(_argv[index], ParameterTypeTraits::type, static_cast(&value)); return value; } @@ -80,7 +59,8 @@ public: ~CLParser(); - +protected: + static void parseString(const std::string& str, ParameterType type, void* value) ; private: std::vector _argv; diff --git a/components/CLParser/include/Modelec/CLParser/Type.h b/components/CLParser/include/Modelec/CLParser/Type.h new file mode 100644 index 0000000..15ba313 --- /dev/null +++ b/components/CLParser/include/Modelec/CLParser/Type.h @@ -0,0 +1,58 @@ +#pragma once +#include + +enum ParameterType +{ + STRING, + INT, + FLOAT, + BOOL, + DOUBLE, + LONG, + SHORT, + CHAR, + CHAR_PTR, + CONST_CHAR_PTR +}; + +template struct ParameterTypeTraits {}; + +template<> struct ParameterTypeTraits { + static constexpr ParameterType type = STRING; +}; + +template<> struct ParameterTypeTraits { + static constexpr ParameterType type = INT; +}; + +template<> struct ParameterTypeTraits { + static constexpr ParameterType type = FLOAT; +}; + +template<> struct ParameterTypeTraits { + static constexpr ParameterType type = BOOL; +}; + +template<> struct ParameterTypeTraits { + static constexpr ParameterType type = DOUBLE; +}; + +template<> struct ParameterTypeTraits { + static constexpr ParameterType type = LONG; +}; + +template<> struct ParameterTypeTraits { + static constexpr ParameterType type = SHORT; +}; + +template<> struct ParameterTypeTraits { + static constexpr ParameterType type = CHAR; +}; + +template<> struct ParameterTypeTraits { + static constexpr ParameterType type = CHAR_PTR; +}; + +template<> struct ParameterTypeTraits { + static constexpr ParameterType type = CONST_CHAR_PTR; +}; diff --git a/components/CLParser/src/CLParser.cpp b/components/CLParser/src/CLParser.cpp index a4fc08e..e742a9f 100644 --- a/components/CLParser/src/CLParser.cpp +++ b/components/CLParser/src/CLParser.cpp @@ -18,26 +18,10 @@ CLParser::CLParser(int argc, char **argv) : _argc(argc) { } } -std::optional CLParser::getOption(const std::string &option) const { - if (!this->hasOption(option)) { - return std::nullopt; - } - - return this->_options.at(option); -} - bool CLParser::hasOption(const std::string &option) const { return this->_options.find(option) != this->_options.end(); } -std::string CLParser::getOption(const std::string &option, const std::string &defaultValue) const { - if (!this->hasOption(option)) { - return defaultValue; - } - - return this->_options.at(option); -} - bool CLParser::hasPositionalArgument(int index) const { return index < this->_argc; } @@ -56,4 +40,45 @@ int CLParser::positionalArgumentsCount() const { CLParser::~CLParser() = default; -CLParser::CLParser(const CLParser &other) = default; \ No newline at end of file +CLParser::CLParser(const CLParser &other) = default; + +void CLParser::parseString(const std::string &str, ParameterType type, void *value) { + try { + switch (type) { + case ParameterType::STRING: + *static_cast(value) = str; + break; + case ParameterType::INT: + *static_cast(value) = std::stoi(str); + break; + case ParameterType::FLOAT: + *static_cast(value) = std::stof(str); + break; + case ParameterType::DOUBLE: + *static_cast(value) = std::stod(str); + break; + case ParameterType::BOOL: + *static_cast(value) = str == "true"; + break; + case ParameterType::LONG: + *static_cast(value) = std::stol(str); + break; + case ParameterType::SHORT: + *static_cast(value) = static_cast(std::stoi(str)); + break; + case ParameterType::CHAR: + *static_cast(value) = str[0]; + break; + case ParameterType::CHAR_PTR: + *static_cast(value) = const_cast(str.c_str()); + break; + case ParameterType::CONST_CHAR_PTR: + *static_cast(value) = str.c_str(); + break; + default: + throw std::runtime_error("Invalid type"); + } + } catch (const std::exception &e) { + throw std::runtime_error("Invalid value for value : " + str); + } +}