-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathp3a_opts.hpp
74 lines (68 loc) · 1.79 KB
/
p3a_opts.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#pragma once
#include <string>
#include <vector>
#include <sstream>
#include <stdexcept>
namespace p3a {
class opt_error : public std::runtime_error {
public:
opt_error(std::string const& arg)
:std::runtime_error(arg)
{}
};
class opt {
std::string m_name;
std::vector<std::string> m_arguments;
bool m_is_set{false};
int m_expected_argument_count{-1};
public:
opt(std::string const& name_arg);
std::string const& name() const;
opt& expect_arguments(int n = -1);
int expected_argument_count() const;
void set();
bool is_set() const;
int argument_count() const;
void add_argument(std::string const& arg);
std::string const& argument(int i) const;
template <class T>
T argument_as(int i) const
{
std::stringstream stream(argument(i));
T result;
stream >> result;
if (stream.fail() || !stream.eof()) {
throw opt_error(
"option " +
m_name +
" argument " +
argument(i) +
" is not convertible to the desired type");
}
return result;
}
};
class opts {
std::vector<opt> m_options;
std::vector<opt> m_positional_options;
public:
opt& add(std::string const& name);
opt& add_positional(std::string const& name);
void parse(int& argc, char** argv, bool allow_unrecognized = false);
bool has(std::string const& name) const;
int argument_count(std::string const& name) const;
std::string const& argument(std::string const& name, int i = 0) const;
template <class T>
T argument_as(std::string const& name, int i = 0) const
{
try {
return get_option(name).argument_as<T>(i);
} catch (opt_error const& e) {
throw opt_error(std::string(e.what()) + "\n" + help_text());
}
}
private:
opt const& get_option(std::string const& name) const;
std::string help_text() const;
};
}