formatting changes
This commit is contained in:
parent
5810494286
commit
ea025ba2fc
52
flags.cpp
52
flags.cpp
@ -1,10 +1,11 @@
|
|||||||
#include "flags.h"
|
#include "flags.h"
|
||||||
#include <sstream>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
namespace Flags {
|
namespace Flags {
|
||||||
|
|
||||||
std::vector<std::string> split(const std::string &input, const char separator) {
|
std::vector<std::string> split(const std::string& input, const char separator) {
|
||||||
std::vector<std::string> result;
|
std::vector<std::string> result;
|
||||||
std::istringstream stream(input);
|
std::istringstream stream(input);
|
||||||
std::string part;
|
std::string part;
|
||||||
@ -14,8 +15,8 @@ std::vector<std::string> split(const std::string &input, const char separator) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool starts_with(const std::string &input, const std::string &start) {
|
bool starts_with(const std::string& input, const std::string& start) {
|
||||||
return (input.size() >= start.size() && input.substr(0, 2) == start);
|
return (input.size() >= start.size() && input.substr(0, start.size()) == start);
|
||||||
}
|
}
|
||||||
|
|
||||||
PARSER(StringFlag, std::string, {
|
PARSER(StringFlag, std::string, {
|
||||||
@ -29,7 +30,7 @@ PARSER(IntFlag, int, {
|
|||||||
try {
|
try {
|
||||||
value = std::stoi(arg);
|
value = std::stoi(arg);
|
||||||
set_parsed(true);
|
set_parsed(true);
|
||||||
} catch (std::exception &) {
|
} catch (std::exception&) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -38,7 +39,7 @@ PARSER(LongIntFlag, long int, {
|
|||||||
try {
|
try {
|
||||||
value = std::stol(arg);
|
value = std::stol(arg);
|
||||||
set_parsed(true);
|
set_parsed(true);
|
||||||
} catch (std::exception &) {
|
} catch (std::exception&) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -47,7 +48,7 @@ PARSER(LongLongIntFlag, long long int, {
|
|||||||
try {
|
try {
|
||||||
value = std::stoll(arg);
|
value = std::stoll(arg);
|
||||||
set_parsed(true);
|
set_parsed(true);
|
||||||
} catch (std::exception &) {
|
} catch (std::exception&) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -56,7 +57,7 @@ PARSER(UnsignedLongIntFlag, unsigned long int, {
|
|||||||
try {
|
try {
|
||||||
value = std::stoul(arg);
|
value = std::stoul(arg);
|
||||||
set_parsed(true);
|
set_parsed(true);
|
||||||
} catch (std::exception &) {
|
} catch (std::exception&) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -65,7 +66,7 @@ PARSER(UnsignedLongLongIntFlag, unsigned long long int, {
|
|||||||
try {
|
try {
|
||||||
value = std::stoull(arg);
|
value = std::stoull(arg);
|
||||||
set_parsed(true);
|
set_parsed(true);
|
||||||
} catch (std::exception &) {
|
} catch (std::exception&) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -74,7 +75,7 @@ PARSER(FloatFlag, float, {
|
|||||||
try {
|
try {
|
||||||
value = std::stof(arg);
|
value = std::stof(arg);
|
||||||
set_parsed(true);
|
set_parsed(true);
|
||||||
} catch (std::exception &) {
|
} catch (std::exception&) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -83,7 +84,7 @@ PARSER(DoubleFlag, double, {
|
|||||||
try {
|
try {
|
||||||
value = stod(arg);
|
value = stod(arg);
|
||||||
set_parsed(true);
|
set_parsed(true);
|
||||||
} catch (std::exception &) {
|
} catch (std::exception&) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -92,36 +93,33 @@ PARSER(LongDoubleFlag, long double, {
|
|||||||
try {
|
try {
|
||||||
value = stold(arg);
|
value = stold(arg);
|
||||||
set_parsed(true);
|
set_parsed(true);
|
||||||
} catch (std::exception &) {
|
} catch (std::exception&) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
PARSER(BoolFlag, bool, {
|
PARSER(BoolFlag, bool, {
|
||||||
std::string copy(arg);
|
std::string copy(arg);
|
||||||
std::transform(copy.begin(), copy.end(), copy.begin(),
|
std::transform(copy.begin(), copy.end(), copy.begin(), [](const char c) { return std::tolower(c); });
|
||||||
[](const char c) { return std::tolower(c); });
|
|
||||||
if (copy == "false")
|
if (copy == "false")
|
||||||
value = false;
|
value = false;
|
||||||
else
|
else
|
||||||
value = true;
|
value = true;
|
||||||
})
|
})
|
||||||
|
|
||||||
Parser::Parser(const std::string &prefix, const std::string &help_text)
|
Parser::Parser(const std::string& prefix, const std::string& help_text) : prefix(prefix), help_text(help_text) {
|
||||||
: prefix(prefix), help_text(help_text) {
|
|
||||||
set_parser<std::string>(flag_constructor_t(StringFlag::make));
|
set_parser<std::string>(flag_constructor_t(StringFlag::make));
|
||||||
set_parser<int>(flag_constructor_t(IntFlag::make));
|
set_parser<int>(flag_constructor_t(IntFlag::make));
|
||||||
set_parser<long int>(flag_constructor_t(LongIntFlag::make));
|
set_parser<long int>(flag_constructor_t(LongIntFlag::make));
|
||||||
set_parser<long long int>(flag_constructor_t(LongLongIntFlag::make));
|
set_parser<long long int>(flag_constructor_t(LongLongIntFlag::make));
|
||||||
set_parser<unsigned long int>(flag_constructor_t(UnsignedLongIntFlag::make));
|
set_parser<unsigned long int>(flag_constructor_t(UnsignedLongIntFlag::make));
|
||||||
set_parser<unsigned long long int>(
|
set_parser<unsigned long long int>(flag_constructor_t(UnsignedLongLongIntFlag::make));
|
||||||
flag_constructor_t(UnsignedLongLongIntFlag::make));
|
|
||||||
set_parser<float>(flag_constructor_t(FloatFlag::make));
|
set_parser<float>(flag_constructor_t(FloatFlag::make));
|
||||||
set_parser<double>(flag_constructor_t(DoubleFlag::make));
|
set_parser<double>(flag_constructor_t(DoubleFlag::make));
|
||||||
set_parser<long double>(flag_constructor_t(LongDoubleFlag::make));
|
set_parser<long double>(flag_constructor_t(LongDoubleFlag::make));
|
||||||
set_parser<bool>(flag_constructor_t(BoolFlag::make));
|
set_parser<bool>(flag_constructor_t(BoolFlag::make));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Parser::parse(int argc, char **argv) {
|
bool Parser::parse(int argc, char** argv) {
|
||||||
// put each argument into a std::string
|
// put each argument into a std::string
|
||||||
std::vector<std::string> args;
|
std::vector<std::string> args;
|
||||||
for (int i = 0; i < argc; i++) {
|
for (int i = 0; i < argc; i++) {
|
||||||
@ -136,15 +134,14 @@ bool Parser::parse(int argc, char **argv) {
|
|||||||
|
|
||||||
// search for flags
|
// search for flags
|
||||||
for (size_t i = 1; i < args.size() - 1; i++) {
|
for (size_t i = 1; i < args.size() - 1; i++) {
|
||||||
const std::string &arg = args[i];
|
const std::string& arg = args[i];
|
||||||
if (starts_with(arg, prefix) && arg.size() > prefix.size()) {
|
if (starts_with(arg, prefix) && arg.size() > prefix.size()) {
|
||||||
flags[arg.substr(prefix.size())]->parse(args[i + 1]);
|
flags[arg.substr(prefix.size())]->parse(args[i + 1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for the last argument
|
// check for the last argument
|
||||||
if (starts_with(args[args.size() - 1], prefix) &&
|
if (starts_with(args[args.size() - 1], prefix) && args[args.size() - 1].size() > prefix.size()) {
|
||||||
args[args.size() - 1].size() > prefix.size()) {
|
|
||||||
flags[args[args.size() - 1].substr(prefix.size())]->parse("");
|
flags[args[args.size() - 1].substr(prefix.size())]->parse("");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,23 +149,18 @@ bool Parser::parse(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned Parser::get_parsed() const {
|
unsigned Parser::get_parsed() const {
|
||||||
return std::count_if(
|
return std::count_if(flags.begin(), flags.end(), [](std::pair<std::string, Flag*> f) { return f.second->get_parsed(); });
|
||||||
flags.begin(), flags.end(),
|
|
||||||
[](std::pair<std::string, Flag *> f) { return f.second->get_parsed(); });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned Parser::get_found() const {
|
unsigned Parser::get_found() const {
|
||||||
return std::count_if(
|
return std::count_if(flags.begin(), flags.end(), [](std::pair<std::string, Flag*> f) { return f.second->get_found(); });
|
||||||
flags.begin(), flags.end(),
|
|
||||||
[](std::pair<std::string, Flag *> f) { return f.second->get_found(); });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::help() const {
|
void Parser::help() const {
|
||||||
std::cout << help_text << std::endl;
|
std::cout << help_text << std::endl;
|
||||||
|
|
||||||
for (auto f : flags) {
|
for (auto f : flags) {
|
||||||
std::cout << '\t' << prefix << f.first << ": "
|
std::cout << '\t' << prefix << f.first << ": " << f.second->get_description() << std::endl;
|
||||||
<< f.second->get_description() << std::endl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // namespace Flags
|
} // namespace Flags
|
73
flags.h
73
flags.h
@ -9,8 +9,8 @@
|
|||||||
namespace Flags {
|
namespace Flags {
|
||||||
|
|
||||||
// utility functions
|
// utility functions
|
||||||
std::vector<std::string> split(const std::string &input, const char separator);
|
std::vector<std::string> split(const std::string& input, const char separator);
|
||||||
bool starts_with(const std::string &input, const std::string &start);
|
bool starts_with(const std::string& input, const std::string& start);
|
||||||
|
|
||||||
// flag base class
|
// flag base class
|
||||||
// should be abstract, don't use
|
// should be abstract, don't use
|
||||||
@ -19,65 +19,62 @@ class Flag {
|
|||||||
bool found;
|
bool found;
|
||||||
bool parsed;
|
bool parsed;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void set_found(const bool found) { this->found = found; }
|
void set_found(const bool found) { this->found = found; }
|
||||||
void set_parsed(const bool parsed) { this->parsed = parsed; }
|
void set_parsed(const bool parsed) { this->parsed = parsed; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual const void *get_value_ptr() const = 0;
|
virtual const void* get_value_ptr() const = 0;
|
||||||
|
|
||||||
Flag(const std::string &description, const bool required)
|
Flag(const std::string& description, const bool required) : description(description), found(!required), parsed(false) {}
|
||||||
: description(description), found(!required), parsed(false) {}
|
|
||||||
|
|
||||||
virtual ~Flag(){};
|
virtual ~Flag(){};
|
||||||
|
|
||||||
const std::string &get_description() const { return description; }
|
const std::string& get_description() const { return description; }
|
||||||
bool get_found() const { return found; }
|
|
||||||
bool get_parsed() const { return parsed; }
|
bool get_parsed() const { return parsed; }
|
||||||
|
bool get_found() const { return found; }
|
||||||
|
|
||||||
virtual void parse(const std::string &arg) = 0;
|
virtual void parse(const std::string& arg) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// type of flag based parser classes' factory functions
|
// type of flag based parser classes' factory functions
|
||||||
typedef std::function<Flag *(const void *, const std::string &, const bool)>
|
typedef std::function<Flag*(const void*, const std::string&, const bool)> flag_constructor_t;
|
||||||
flag_constructor_t;
|
|
||||||
|
|
||||||
// use this class to create your own parser
|
// use this class to create your own parser
|
||||||
template <typename T> class FlagTemplate : public Flag {
|
template <typename T>
|
||||||
protected:
|
class FlagTemplate : public Flag {
|
||||||
|
protected:
|
||||||
T value;
|
T value;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit FlagTemplate<T>(const void *default_value,
|
explicit FlagTemplate<T>(const void* default_value, const std::string& description, const bool required)
|
||||||
const std::string &description, const bool required)
|
: Flag(description, required), value(*(T*)default_value) {}
|
||||||
: Flag(description, required), value(*(T *)default_value) {}
|
|
||||||
|
|
||||||
const void *get_value_ptr() const override { return &value; };
|
const void* get_value_ptr() const override { return &value; };
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PARSER(name, type, func) \
|
#define PARSER(name, type, func) \
|
||||||
class name : public FlagTemplate<type> { \
|
class name : public FlagTemplate<type> { \
|
||||||
using FlagTemplate<type>::FlagTemplate; \
|
using FlagTemplate<type>::FlagTemplate; \
|
||||||
\
|
\
|
||||||
public: \
|
public: \
|
||||||
static Flag *make(const void *default_value, \
|
static Flag* make(const void* default_value, const std::string& description, const bool required) { \
|
||||||
const std::string &description, const bool required) { \
|
return new name(default_value, description, required); \
|
||||||
return new name(default_value, description, required); \
|
} \
|
||||||
} \
|
void parse(const std::string& arg) override func \
|
||||||
void parse(const std::string &arg) override func \
|
|
||||||
}; // namespace Flags
|
}; // namespace Flags
|
||||||
|
|
||||||
// flag holder, parsing orchestrator
|
// flag holder, parsing orchestrator
|
||||||
class Parser {
|
class Parser {
|
||||||
private:
|
private:
|
||||||
const std::string prefix;
|
const std::string prefix;
|
||||||
const std::string help_text;
|
const std::string help_text;
|
||||||
|
|
||||||
std::map<std::string, Flag *> flags;
|
std::map<std::string, Flag*> flags;
|
||||||
std::map<std::type_index, flag_constructor_t> constructors;
|
std::map<std::type_index, flag_constructor_t> constructors;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Parser(const std::string &prefix, const std::string &help_text);
|
Parser(const std::string& prefix, const std::string& help_text);
|
||||||
|
|
||||||
Parser() : Parser("--", "Help:") {}
|
Parser() : Parser("--", "Help:") {}
|
||||||
|
|
||||||
@ -93,18 +90,16 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T *add(const std::string &name, const std::string &description,
|
T* add(const std::string& name, const std::string& description, const bool required, T default_value) {
|
||||||
const bool required, T default_value) {
|
flags[name] = constructors[typeid(T)]((void*)&default_value, description, required);
|
||||||
flags[name] =
|
return (T*)flags[name]->get_value_ptr();
|
||||||
constructors[typeid(T)]((void *)&default_value, description, required);
|
|
||||||
return (T *)flags[name]->get_value_ptr();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned get_found() const;
|
unsigned get_found() const;
|
||||||
|
|
||||||
unsigned get_parsed() const;
|
unsigned get_parsed() const;
|
||||||
|
|
||||||
bool parse(int argc, char **argv);
|
bool parse(int argc, char** argv);
|
||||||
|
|
||||||
void help() const;
|
void help() const;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user