-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparser.h
135 lines (121 loc) · 3.59 KB
/
parser.h
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
//
// Created by Тимофей Жамойдин on 23.10.22.
//
#pragma once
#include <functional>
#include <vector>
#include <string>
#include <tuple>
#include "my_exceptions.h"
#include "constants.h"
class Encoded {
public:
Encoded() = default;
explicit Encoded(const std::vector<std::string_view>& s);
public:
std::string archive_name;
std::vector<std::string_view> files;
};
Encoded::Encoded(const std::vector<std::string_view>& s) {
if (s.size() < 2) {
throw BadArgumentException(LOW_ARGS);
}
archive_name = s[0];
files.insert(files.end(), s.begin() + 1, s.end());
}
class Decoded {
public:
Decoded() = default;
explicit Decoded(const std::vector<std::string_view>& s);
public:
std::string archive_name;
};
Decoded::Decoded(const std::vector<std::string_view>& s) {
if (s.size() != 1) {
throw BadArgumentException(ARGS_ERROR);
}
archive_name = s[0];
}
class Help {
public:
Help() = default;
explicit Help(const std::vector<std::string_view>& s);
};
Help::Help(const std::vector<std::string_view>& s) {
}
template <typename ARGTYPE>
class Instruction {
public:
Instruction(std::function<bool(std::string)> checker, std::function<void(ARGTYPE)> instruction);
bool Check(int argc, char** argv);
void Execute();
private:
std::function<bool(std::string)> checker_;
ARGTYPE argument_;
std::function<void(ARGTYPE)> instruction_;
};
template <typename ARGTYPE>
bool Instruction<ARGTYPE>::Check(int argc, char** argv) {
if (argc <= 1) {
return false;
}
auto first_parameter = std::string(argv[1]);
if (checker_(first_parameter)) {
std::vector<std::string_view> other;
for (size_t i = 2; i < argc; ++i) {
other.push_back(std::string_view(argv[i]));
}
argument_ = ARGTYPE(other);
return true;
}
return false;
}
template <typename ARGTYPE>
void Instruction<ARGTYPE>::Execute() {
instruction_(argument_);
}
template <typename ARGTYPE>
Instruction<ARGTYPE>::Instruction(std::function<bool(std::string)> checker, std::function<void(ARGTYPE)> instruction)
: checker_(checker), instruction_(instruction) {
}
template <class... ARGS>
class Parser {
public:
explicit Parser(const std::tuple<ARGS...>& args);
template <size_t CNT = 0, typename... T>
typename std::enable_if<CNT == sizeof...(T) - 1, void>::type ExecuteTuple(std::tuple<T...> tup, int argc,
char** argv) {
std::get<CNT>(tup).Check(argc, argv);
std::get<CNT>(tup).Execute();
}
template <size_t CNT = 0, typename... T>
typename std::enable_if<(CNT < sizeof...(T) - 1), void>::type ExecuteTuple(std::tuple<T...> tup, int argc,
char** argv) {
auto handler = std::get<CNT>(tup);
if (handler.Check(argc, argv)) {
handler.Execute();
return;
}
ExecuteTuple<CNT + 1>(tup, argc, argv);
}
void Execute(int argc, char** argv);
private:
std::tuple<ARGS...> args_;
};
template <class... ARGS>
Parser<ARGS...>::Parser(const std::tuple<ARGS...>& args) : args_(args) {
}
template <class... ARGS>
void Parser<ARGS...>::Execute(int argc, char** argv) {
ExecuteTuple(args_, argc, argv);
}
class FlagType {
public:
explicit FlagType(const std::vector<std::string>& flags) : flags_(flags) {
}
bool operator()(std::string pos) {
return std::find(flags_.begin(), flags_.end(), pos) != flags_.end();
}
private:
std::vector<std::string> flags_;
};