New ways to transform string (inspired by open cv command line parser class)

This commit is contained in:
ackimixs
2024-05-21 22:22:18 +02:00
parent 782e498510
commit 581b90b035
3 changed files with 113 additions and 50 deletions

View File

@@ -7,6 +7,8 @@
#include <iostream>
#include <vector>
#include <Modelec/CLParser/Type.h>
class CLParser {
public:
@@ -16,42 +18,25 @@ public:
[[nodiscard]] bool hasOption(const std::string& option) const;
[[nodiscard]] std::optional<std::string> getOption(const std::string& option) const;
[[nodiscard]] std::string getOption(const std::string& option, const std::string& defaultValue) const;
template <typename T>
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<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<T>::type, static_cast<void *>(&value));
return value;
}
template <typename T>
[[nodiscard]] std::optional<std::enable_if_t<std::is_arithmetic_v<T>, T>> getOption(const std::string& option) const {
[[nodiscard]] std::optional<T> 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<T>::type, static_cast<void *>(&value));
return value;
}
@@ -60,19 +45,13 @@ public:
[[nodiscard]] std::string getPositionalArgument(int index) const;
template <typename T>
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<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<T>::type, static_cast<void *>(&value));
return value;
}
@@ -80,7 +59,8 @@ public:
~CLParser();
protected:
static void parseString(const std::string& str, ParameterType type, void* value) ;
private:
std::vector<std::string> _argv;

View File

@@ -0,0 +1,58 @@
#pragma once
#include <string>
enum ParameterType
{
STRING,
INT,
FLOAT,
BOOL,
DOUBLE,
LONG,
SHORT,
CHAR,
CHAR_PTR,
CONST_CHAR_PTR
};
template<typename T> struct ParameterTypeTraits {};
template<> struct ParameterTypeTraits<std::string> {
static constexpr ParameterType type = STRING;
};
template<> struct ParameterTypeTraits<int> {
static constexpr ParameterType type = INT;
};
template<> struct ParameterTypeTraits<float> {
static constexpr ParameterType type = FLOAT;
};
template<> struct ParameterTypeTraits<bool> {
static constexpr ParameterType type = BOOL;
};
template<> struct ParameterTypeTraits<double> {
static constexpr ParameterType type = DOUBLE;
};
template<> struct ParameterTypeTraits<long> {
static constexpr ParameterType type = LONG;
};
template<> struct ParameterTypeTraits<short> {
static constexpr ParameterType type = SHORT;
};
template<> struct ParameterTypeTraits<char> {
static constexpr ParameterType type = CHAR;
};
template<> struct ParameterTypeTraits<char*> {
static constexpr ParameterType type = CHAR_PTR;
};
template<> struct ParameterTypeTraits<const char*> {
static constexpr ParameterType type = CONST_CHAR_PTR;
};

View File

@@ -18,26 +18,10 @@ CLParser::CLParser(int argc, char **argv) : _argc(argc) {
}
}
std::optional<std::string> 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;
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<std::string *>(value) = str;
break;
case ParameterType::INT:
*static_cast<int *>(value) = std::stoi(str);
break;
case ParameterType::FLOAT:
*static_cast<float *>(value) = std::stof(str);
break;
case ParameterType::DOUBLE:
*static_cast<double *>(value) = std::stod(str);
break;
case ParameterType::BOOL:
*static_cast<bool *>(value) = str == "true";
break;
case ParameterType::LONG:
*static_cast<long *>(value) = std::stol(str);
break;
case ParameterType::SHORT:
*static_cast<short *>(value) = static_cast<short>(std::stoi(str));
break;
case ParameterType::CHAR:
*static_cast<char *>(value) = str[0];
break;
case ParameterType::CHAR_PTR:
*static_cast<char **>(value) = const_cast<char *>(str.c_str());
break;
case ParameterType::CONST_CHAR_PTR:
*static_cast<const char **>(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);
}
}