Covalent Bond  0.0.1-alpha
'covalent bond' is a data middle office. As a 2022-2023 Fall SWE final project.
argparse.hpp
Go to the documentation of this file.
1 
6 #ifndef H_ARGPARSE_
7 #define H_ARGPARSE_
8 
10 #if _MSC_VER > 1000
11 #pragma once
12 #endif
13 
14 #include <iostream>
15 #include <string>
16 #include <map>
17 #include <cstring>
18 #include <vector>
19 
20 namespace argp {
21 using namespace std;
22 
23 enum class arg_type {
24  t_none = 0,
25  t_int,
26  t_uint,
27  t_float,
28  t_double,
29  t_string,
30  t_object
31 };
32 
34  arg_payload_obj() = default;
35  arg_payload_obj(arg_type type, bool is_necessary) : _type(type), _is_necessary(is_necessary){};
36  arg_type _type;
37  string _name;
38  string _s_name;
39  bool _is_empty = true;
41 };
42 
43 template<typename T>
44 struct arg_payload : public arg_payload_obj {
45  arg_payload() = default;
46  arg_payload(arg_type type, bool is_necessary, T default_v)
47  : arg_payload_obj(type, is_necessary), _default_v(default_v){};
48 
49  T _default_v;
51 };
52 
53 class parser {
54  public:
55  parser() = default;
56  ~parser() {
57  for (auto& item : m_k_v) { delete item.second; }
58  };
59 
60  public:
61  template<typename T>
62  void add_arg(const string& name, const string& s_name, arg_type type, T default_v,
63  bool is_necessary) {
64  auto ptr = new arg_payload<T>(type, is_necessary, default_v);
65  ptr->_setted_v = default_v;
66  ptr->_name = name.substr(2, name.length() - 2);
67  ptr->_s_name = s_name.substr(1, name.length() - 1);
68  _add_arg_(name, ptr);
69  }
70 
71  template<typename T>
72  void add_arg(const string& name, const string& s_name, arg_type type, bool is_necessary) {
73  auto ptr = new arg_payload<T>();
74  ptr->_type = type;
75  ptr->_is_necessary = is_necessary;
76  ptr->_name = name.substr(2, name.length() - 2);
77  ptr->_s_name = s_name.substr(1, name.length() - 1);
78  _add_arg_(name, ptr);
79  }
80 
84  void add_arg(const string& name, const string& s_name, bool is_necessary) {
85  auto ptr = new arg_payload<bool>(arg_type::t_none, is_necessary, true);
86  ptr->_name = name.substr(2, name.length() - 2);
87  ptr->_s_name = s_name.substr(1, name.length() - 1);
88  ptr->_setted_v = true;
89  _add_arg_(name, ptr);
90  }
91 
92  template<typename T>
93  void _add_arg_(const string& name, arg_payload<T>* arg_ptr) {
94  m_k_v[name.substr(2, name.length() - 2)] = arg_ptr;
95  }
96 
97  template<typename T>
98  T& get_item(const string& key) {
99  /* only full name support */
100  if (!m_parsed) { cout << "[Warn] You should call .parse function before get_item\n"; }
101 
102  auto ptr = m_k_v[key];
103  auto ptr_c = (arg_payload<T>*)ptr;
104  return ptr_c->_setted_v;
105  }
106 
107  bool has_item(const string& key) {
108  /* only full name support */
109  return !m_k_v[key]->_is_empty;
110  }
111 
112  virtual bool parse(int argc, char** args) {
113  m_current_prog = string(args[0]);
114  for (int i = 0; i < argc; ++i) { m_visited.push_back(false); }
115  m_visited[0] = true;
116  for (auto& item : m_k_v) {
117  string tmp_name = "--" + item.second->_name;
118  string tmp_s_name = "-" + item.second->_s_name;
119  for (int i = 1; i < argc;) {
120  if ((!strcmp(tmp_name.c_str(), args[i])) || (!strcmp(tmp_s_name.c_str(), args[i]))) {
121  item.second->_is_empty = false;
122  arg_type tmp_type = item.second->_type;
123  m_visited[i] = true;
124  if (tmp_type == arg_type::t_none) {
125  } else if (tmp_type == arg_type::t_float) {
126  auto ptr = item.second;
127  auto ptr_c = (arg_payload<float>*)ptr;
128  m_visited[i + 1] = true;
129  ptr_c->_setted_v = atof(args[++i]);
130  } else if (tmp_type == arg_type::t_double) {
131  auto ptr = item.second;
132  auto ptr_c = (arg_payload<double>*)ptr;
133  m_visited[i + 1] = true;
134  ptr_c->_setted_v = (double)atof(args[++i]);
135  } else if (tmp_type == arg_type::t_int) {
136  auto ptr = item.second;
137  auto ptr_c = (arg_payload<int>*)ptr;
138  m_visited[i + 1] = true;
139  ptr_c->_setted_v = atoi(args[++i]);
140  } else if (tmp_type == arg_type::t_uint) {
141  auto ptr = item.second;
142  auto ptr_c = (arg_payload<unsigned int>*)ptr;
143  m_visited[i + 1] = true;
144  ptr_c->_setted_v = (unsigned int)atoi(args[++i]);
145  } else if (tmp_type == arg_type::t_string) {
146  auto ptr = item.second;
147  auto ptr_c = (arg_payload<string>*)ptr;
148  m_visited[i + 1] = true;
149  ptr_c->_setted_v = string(args[++i]);
150  }
151  }
152  ++i;
153  }
154  }
155 
156  if (!m_visited.empty()) {
157  int cnt = 0;
158  for (auto idx : m_visited) {
159  if (!idx) { m_others.push_back(string(args[cnt])); }
160  cnt++;
161  }
162  }
163 
164  if (!m_others.empty()) {
165  cout << "[Warn] Found other args:\n";
166  for (auto& item : m_others) { cout << item << "\n"; }
167  }
168 
169  m_parsed = true;
170  return true;
171  }
172 
173  virtual void show_all_parsed() {
174  show_all_defined();
175  // show others undefined or no-name value.
176  }
177 
178  virtual void show_all_defined() {
179  for (auto& item : m_k_v) {
180  switch (item.second->_type) {
181  case arg_type::t_int: {
182  auto ptr = (arg_payload<int>*)item.second;
183  cout << "--" << ptr->_name << " -" << ptr->_s_name << " ";
184  cout << "Defualt is: " << ptr->_default_v << " ";
185  cout << "Setted value is: " << ptr->_setted_v << endl;
186  } break;
187  case arg_type::t_uint: {
188  auto ptr = (arg_payload<unsigned int>*)item.second;
189  cout << "--" << ptr->_name << " -" << ptr->_s_name << " ";
190  cout << "Defualt is: " << ptr->_default_v << " ";
191  cout << "Setted value is: " << ptr->_setted_v << endl;
192  } break;
193  case arg_type::t_float: {
194  auto ptr = (arg_payload<float>*)item.second;
195  cout << "--" << ptr->_name << " -" << ptr->_s_name << " ";
196  cout << "Defualt is: " << ptr->_default_v << " ";
197  cout << "Setted value is: " << ptr->_setted_v << endl;
198  } break;
199  case arg_type::t_double: {
200  auto ptr = (arg_payload<double>*)item.second;
201  cout << "--" << ptr->_name << " -" << ptr->_s_name << " ";
202  cout << "Defualt is: " << ptr->_default_v << " ";
203  cout << "Setted value is: " << ptr->_setted_v << endl;
204  } break;
205  case arg_type::t_string: {
206  auto ptr = (arg_payload<string>*)item.second;
207  cout << "--" << ptr->_name << " -" << ptr->_s_name << " ";
208  cout << "Defualt is: " << ptr->_default_v << " ";
209  cout << "Setted value is: " << ptr->_setted_v << endl;
210  } break;
211  case arg_type::t_none: {
212  auto ptr = (arg_payload<string>*)item.second;
213  cout << "--" << ptr->_name << " -" << ptr->_s_name << " ";
214  cout << "is a no value flag" << endl;
215  } break;
216  default: break;
217  }
218  }
219  }
220 
221  protected:
222  bool m_parsed = false;
223  map<string, arg_payload_obj*> m_k_v;
225  vector<bool> m_visited;
226  vector<string> m_others;
227 };
228 
229 } // namespace argp
230 
231 #endif
argp::parser::show_all_defined
virtual void show_all_defined()
Definition: argparse.hpp:178
argp::parser::parse
virtual bool parse(int argc, char **args)
Definition: argparse.hpp:112
argp::parser::_add_arg_
void _add_arg_(const string &name, arg_payload< T > *arg_ptr)
Definition: argparse.hpp:93
argp::parser::add_arg
void add_arg(const string &name, const string &s_name, bool is_necessary)
This function for no value flags.
Definition: argparse.hpp:84
argp::arg_payload_obj::_name
string _name
Definition: argparse.hpp:37
argp::parser::has_item
bool has_item(const string &key)
Definition: argparse.hpp:107
argp::arg_payload_obj::arg_payload_obj
arg_payload_obj(arg_type type, bool is_necessary)
Definition: argparse.hpp:35
argp::arg_type::t_uint
@ t_uint
argp::arg_type::t_float
@ t_float
argp::parser::~parser
~parser()
Definition: argparse.hpp:56
argp::parser::add_arg
void add_arg(const string &name, const string &s_name, arg_type type, bool is_necessary)
Definition: argparse.hpp:72
argp::arg_payload_obj::_is_necessary
bool _is_necessary
Definition: argparse.hpp:40
argp::parser::m_current_prog
string m_current_prog
Definition: argparse.hpp:224
argp::arg_payload::_setted_v
T _setted_v
Definition: argparse.hpp:50
argp::parser::add_arg
void add_arg(const string &name, const string &s_name, arg_type type, T default_v, bool is_necessary)
Definition: argparse.hpp:62
argp::arg_type
arg_type
Definition: argparse.hpp:23
argp::parser::get_item
T & get_item(const string &key)
Definition: argparse.hpp:98
argp::arg_payload_obj
Definition: argparse.hpp:33
argp::parser::m_visited
vector< bool > m_visited
Definition: argparse.hpp:225
argp::arg_payload
Definition: argparse.hpp:44
argp::parser
Definition: argparse.hpp:53
argp::parser::m_others
vector< string > m_others
Definition: argparse.hpp:226
argp::arg_type::t_double
@ t_double
argp::arg_type::t_int
@ t_int
argp::arg_type::t_string
@ t_string
argp::parser::m_k_v
map< string, arg_payload_obj * > m_k_v
Definition: argparse.hpp:223
argp::arg_payload_obj::_s_name
string _s_name
Definition: argparse.hpp:38
argp::arg_type::t_object
@ t_object
argp::arg_type::t_none
@ t_none
for no value.
argp::arg_payload::arg_payload
arg_payload(arg_type type, bool is_necessary, T default_v)
Definition: argparse.hpp:46
argp
A simple approach for arg-parse.
Definition: argparse.hpp:20
argp::parser::show_all_parsed
virtual void show_all_parsed()
Definition: argparse.hpp:173