Skip to content

Commit

Permalink
BREAKING CHANGE: Options::Options -> Options::Parser
Browse files Browse the repository at this point in the history
Renamed class for better readability.
  • Loading branch information
opokatech committed May 4, 2024
1 parent c5a01ab commit 33bae8b
Show file tree
Hide file tree
Showing 8 changed files with 246 additions and 247 deletions.
1 change: 0 additions & 1 deletion .clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ Checks: '-checks=-*,bugprone-*,clang-analyzer-*,cppcoreguidelines-*,rea

WarningsAsErrors: ''
HeaderFilterRegex: ''
AnalyzeTemporaryDtors: false
FormatStyle: none
CheckOptions:
- key: readability-identifier-naming.ClassCase
Expand Down
52 changes: 26 additions & 26 deletions src/example/example.cpp
Original file line number Diff line number Diff line change
@@ -1,59 +1,59 @@
#include <iostream>

#include "options/Converters.hpp"
#include "options/Options.hpp"
#include "options/Parser.hpp"

int main(int argc, char *argv[])
{
using std::cout;
using std::endl;

Options::Options opts;
Options::Parser args_parser;

opts.add_flag("help", 'h', "This help is accessible via short and long option");
opts.add_flag("verbose", 'v', "Verbose - accessible via -v and --verbose");
opts.add_optional(
args_parser.add_flag("help", 'h', "This help is accessible via short and long option");
args_parser.add_flag("verbose", 'v', "Verbose - accessible via -v and --verbose");
args_parser.add_optional(
"level", "Debug level, one of none, debug, error - it is checked by the validator", "none",
[](const std::string &value) { return (value == "none" || value == "debug" || value == "error"); });

opts.add_mandatory("config", 'c', "Configuration file");
opts.add_optional("int", 'i', "Some small integer in range <-10..10> as checked by validator", "4",
[](const std::string &value) {
int32_t num = Options::as_int(value);
return num >= -10 && num <= 10; // NOLINT
});
opts.add_optional("double", 'd', "Double value > 3.0", "3.14", [](const std::string &value) {
args_parser.add_mandatory("config", 'c', "Configuration file");
args_parser.add_optional("int", 'i', "Some small integer in range <-10..10> as checked by validator", "4",
[](const std::string &value) {
int32_t num = Options::as_int(value);
return num >= -10 && num <= 10; // NOLINT
});
args_parser.add_optional("double", 'd', "Double value > 3.0", "3.14", [](const std::string &value) {
double num = Options::as_double(value);
return num > 3.0; // NOLINT
});

opts.add_optional("bf", "Boolean value", "false");
opts.add_optional("bt", "Boolean value", "true");
args_parser.add_optional("bf", "Boolean value", "false");
args_parser.add_optional("bt", "Boolean value", "true");

if (!opts.parse(argc, argv) || opts.as_bool("help"))
if (!args_parser.parse(argc, argv) || args_parser.as_bool("help"))
{
cout << "Usage: " << argv[0] << " [options] [-- [positional arguments]]" << endl;
cout << opts.get_possible_options() << endl;
cout << args_parser.get_possible_options() << endl;
return -1;
}

cout << std::boolalpha;
cout << "Options:" << endl;
cout << " verbose : " << opts.as_bool("verbose") << endl;
cout << " level : " << opts.as_string("level") << endl;
cout << " config : " << opts.as_string("config") << endl;
cout << " int : " << opts.as_int("int") << endl;
cout << " double : " << opts.as_double("double") << endl;
cout << " bf : " << opts.as_bool("bf") << endl;
cout << " bt : " << opts.as_bool("bt") << endl;
cout << " verbose : " << args_parser.as_bool("verbose") << endl;
cout << " level : " << args_parser.as_string("level") << endl;
cout << " config : " << args_parser.as_string("config") << endl;
cout << " int : " << args_parser.as_int("int") << endl;
cout << " double : " << args_parser.as_double("double") << endl;
cout << " bf : " << args_parser.as_bool("bf") << endl;
cout << " bt : " << args_parser.as_bool("bt") << endl;

// positional arguments are all the strings after "--" separator, for example:
// ./example -c config_file.txt -v -- these strings are positional arguments
if (opts.positional_count() > 0)
if (args_parser.positional_count() > 0)
{
cout << "Positional parameters:" << endl;
for (size_t i = 0; i < opts.positional_count(); ++i)
cout << " [" << i << "]: " << opts.positional(i) << endl;
for (size_t i = 0; i < args_parser.positional_count(); ++i)
cout << " [" << i << "]: " << args_parser.positional(i) << endl;
}
else
cout << "No positional parameters." << endl;
Expand Down
2 changes: 1 addition & 1 deletion src/options/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
add_library(options STATIC Converters.cpp Option.cpp Options.cpp)
add_library(options STATIC Converters.cpp Option.cpp Parser.cpp)
target_include_directories(options PUBLIC ..)
target_link_libraries(options PRIVATE options_compile_flags)
44 changes: 22 additions & 22 deletions src/options/Options.cpp → src/options/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
#include <vector>

#include "Option.hpp"
#include "Options.hpp"
#include "Parser.hpp"

namespace Options
{
struct Options::Impl
struct Parser::Impl
{
// This will throw an exception if the option is not found.
std::vector<Option>::const_iterator find_option_by_long_name(const std::string &name) const
Expand Down Expand Up @@ -52,47 +52,47 @@ namespace Options
std::vector<std::string> _positional;
};

Options::Options() : _impl(new Impl) {}
Parser::Parser() : _impl(new Impl) {}

Options::~Options()
Parser::~Parser()
{
delete _impl;
}

void Options::add_flag(const std::string &long_name, char short_name, const std::string &description)
void Parser::add_flag(const std::string &long_name, char short_name, const std::string &description)
{
_impl->add({long_name, short_name, description});
}

void Options::add_flag(const std::string &long_name, const std::string &description)
void Parser::add_flag(const std::string &long_name, const std::string &description)
{
add_flag(long_name, Option::SHORT_NOT_USED, description);
}

void Options::add_optional(const std::string &long_name, char short_name, const std::string &description,
const std::string &default_value, validator_t validator)
void Parser::add_optional(const std::string &long_name, char short_name, const std::string &description,
const std::string &default_value, validator_t validator)
{
_impl->add({long_name, short_name, description}).set_optional(default_value).set_validator(validator);
}

void Options::add_optional(const std::string &long_name, const std::string &description,
const std::string &default_value, validator_t validator)
void Parser::add_optional(const std::string &long_name, const std::string &description,
const std::string &default_value, validator_t validator)
{
add_optional(long_name, Option::SHORT_NOT_USED, description, default_value, validator);
}

void Options::add_mandatory(const std::string &long_name, char short_name, const std::string &description,
validator_t validator)
void Parser::add_mandatory(const std::string &long_name, char short_name, const std::string &description,
validator_t validator)
{
_impl->add({long_name, short_name, description}).set_mandatory().set_validator(validator);
}

void Options::add_mandatory(const std::string &long_name, const std::string &description, validator_t validator)
void Parser::add_mandatory(const std::string &long_name, const std::string &description, validator_t validator)
{
add_mandatory(long_name, Option::SHORT_NOT_USED, description, validator);
}

bool Options::parse(int argc, const char *const *argv, int start_idx)
bool Parser::parse(int argc, const char *const *argv, int start_idx)
{
int pos = start_idx;

Expand Down Expand Up @@ -140,42 +140,42 @@ namespace Options
return std::all_of(_impl->_options.cbegin(), _impl->_options.cend(), NON_MANDATORY_OR_FOUND);
}

size_t Options::positional_count() const
size_t Parser::positional_count() const
{
return _impl->_positional.size();
}

const std::string &Options::positional(size_t idx) const
const std::string &Parser::positional(size_t idx) const
{
return _impl->_positional.at(idx);
}

int32_t Options::as_int(const std::string &name) const
int32_t Parser::as_int(const std::string &name) const
{
return _impl->find_option_by_long_name(name)->as_int();
}

uint32_t Options::as_uint(const std::string &name) const
uint32_t Parser::as_uint(const std::string &name) const
{
return _impl->find_option_by_long_name(name)->as_uint();
}

double Options::as_double(const std::string &name) const
double Parser::as_double(const std::string &name) const
{
return _impl->find_option_by_long_name(name)->as_double();
}

bool Options::as_bool(const std::string &name) const
bool Parser::as_bool(const std::string &name) const
{
return _impl->find_option_by_long_name(name)->as_bool();
}

const std::string &Options::as_string(const std::string &name) const
const std::string &Parser::as_string(const std::string &name) const
{
return _impl->find_option_by_long_name(name)->as_string();
}

std::string Options::get_possible_options() const
std::string Parser::get_possible_options() const
{
std::stringstream sstream;

Expand Down
16 changes: 8 additions & 8 deletions src/options/Options.hpp → src/options/Parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

namespace Options
{
/* Class Options.
/* Class Parser.
*
* This class defines expected and possible options passed to the program.
*
Expand All @@ -33,17 +33,17 @@ namespace Options
*
* Extensive example of how to use this class is in example/example.cpp.
*/
class Options
class Parser
{
public:
Options();
~Options();
Parser();
~Parser();

// explicitly disallow copying in any form
Options(const Options &) = delete;
Options(Options &&) = delete;
Options &operator=(const Options &) = delete;
Options &operator=(Options &&) = delete;
Parser(const Parser &) = delete;
Parser(Parser &&) = delete;
Parser &operator=(const Parser &) = delete;
Parser &operator=(Parser &&) = delete;

void add_flag(const std::string &long_name, char short_name, const std::string &description);

Expand Down
2 changes: 1 addition & 1 deletion src/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ message(STATUS "Catch2 ready")

enable_testing()

add_executable(${PROJECT_NAME}_tests Option_Test.cpp Options_Test.cpp)
add_executable(${PROJECT_NAME}_tests Option_Test.cpp Parser_Test.cpp)
target_link_libraries(${PROJECT_NAME}_tests PRIVATE options options_tests_compile_flags Catch2WithMain)
Loading

0 comments on commit 33bae8b

Please sign in to comment.