-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathCommandLineInterface.hh
More file actions
130 lines (115 loc) · 3.95 KB
/
CommandLineInterface.hh
File metadata and controls
130 lines (115 loc) · 3.95 KB
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
#ifndef __COMMAND_LINE_INTERFACE
#define __COMMAND_LINE_INTERFACE
#include <stdint.h> //for uint* types
#include <iostream>
#include <iomanip>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <typeinfo>
#include <cxxabi.h>
class CommandLineInterface {
public:
CommandLineInterface();
~CommandLineInterface(){};
//main functions to check all flags from command line
bool CheckFlags(int,char*[],const bool& Debug = false);
void Help(char*);
//functions to add flags
void Add(const char*); // add a pure comment (no flag)
template<typename T>
void Add(const char*, const char*, T*); // add a simple flag
template<typename T>
void Add(const char*, const char*, std::vector<T>*); // add a flag using a vector of variables
void Add(const char*, const char*, double*, double factor = 1.);
void Add(const char*, const char*, std::vector<double>*, double factor = 1.);
friend std::ostream& operator <<(std::ostream &,const CommandLineInterface &);
private:
bool FlagExists(const char*);
// flags
size_t fMaximumFlagLength;
std::vector<std::string> fFlags;
// values
std::vector<void*> fValues;
// types
size_t fMaximumTypeLength;
std::vector<std::string> fTypes;
// comments
size_t fMaximumCommentLength;
std::vector<std::string> fComments;
// factors
std::vector<double> fFactors;
};
template<typename T>
void CommandLineInterface::Add(const char* flag, const char* comment, T* value)
{
// check if the flag already exists, otherwise add the new flag and value
if(FlagExists(flag)) return;
if(strlen(flag) > fMaximumFlagLength) fMaximumFlagLength = strlen(flag);
fFlags.push_back(std::string(flag));
fValues.push_back((void*) value);
// demangle the type and add it to the type vector
int status;
char* type = abi::__cxa_demangle(typeid(T).name(), 0, 0, &status);
if(status != 0) {
std::cerr<<__PRETTY_FUNCTION__<<": failed to demangle type '"<<typeid(T).name()<<"' status "<<status<<std::endl;
return;
}
// make "std::string" more readable
if(strcmp(type,"std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >") == 0) {
if(11 > fMaximumTypeLength) {
fMaximumTypeLength = 11;
}
fTypes.push_back(std::string("std::string"));
} else {
if(strlen(type) > fMaximumTypeLength) {
fMaximumTypeLength = strlen(type);
}
fTypes.push_back(std::string(type));
}
// update comment length and add comment
if(strlen(comment) > fMaximumCommentLength) {
fMaximumCommentLength = strlen(comment);
}
fComments.push_back(std::string(comment));
// not using any factors here (why? could just use default=1?)
fFactors.push_back(1.);
free(type);
}
template<typename T>
void CommandLineInterface::Add(const char* flag, const char* comment, std::vector<T>* value)
{
// check if the flag already exists, otherwise add the new flag and value
if(FlagExists(flag)) return;
if(strlen(flag) > fMaximumFlagLength) fMaximumFlagLength = strlen(flag);
fFlags.push_back(std::string(flag));
fValues.push_back((void*) value);
// demangle the type and add it to the type vector
int status;
char* type = abi::__cxa_demangle(typeid(T).name(), 0, 0, &status);
if(status != 0) {
std::cerr<<__PRETTY_FUNCTION__<<": failed to demangle type '"<<typeid(T).name()<<"' status "<<status<<std::endl;
return;
}
// make "std::string" more readable
if(strcmp(type,"std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >") == 0) {
if(24 > fMaximumTypeLength) {
fMaximumTypeLength = 24;
}
fTypes.push_back(std::string("std::vector<std::string>"));
} else {
if(strlen(type)+13 > fMaximumTypeLength) {
fMaximumTypeLength = strlen(type)+13;
}
fTypes.push_back(std::string("std::vector<")+std::string(type)+std::string(">"));
}
// update comment length and add comment
if(strlen(comment) > fMaximumCommentLength) {
fMaximumCommentLength = strlen(comment);
}
fComments.push_back(std::string(comment));
// not using any factors here (why? could just use default=1?)
fFactors.push_back(1.);
free(type);
}
#endif