39 private: |
39 private: |
40 char _shortform; |
40 char _shortform; |
41 String _longform; |
41 String _longform; |
42 String _description; |
42 String _description; |
43 std::type_info const* _type; |
43 std::type_info const* _type; |
44 void* _ptr; |
44 |
|
45 union PointerUnion |
|
46 { |
|
47 int* asInt; |
|
48 long* asLong; |
|
49 char* asChar; |
|
50 bool* asBool; |
|
51 String* asString; |
|
52 double* asDouble; |
|
53 |
|
54 PointerUnion (int* a) : asInt (a) {} |
|
55 PointerUnion (bool* a) : asBool (a) {} |
|
56 PointerUnion (String* a) : asString (a) {} |
|
57 PointerUnion (double* a) : asDouble (a) {} |
|
58 PointerUnion (long* a) : asLong (a) {} |
|
59 PointerUnion (char* a) : asChar (a) {} |
|
60 |
|
61 void setValue (int const& a) { *asInt = a; } |
|
62 void setValue (bool const& a) { *asBool = a; } |
|
63 void setValue (String const& a) { *asString = a; } |
|
64 void setValue (double const& a) { *asDouble = a; } |
|
65 void setValue (long const& a) { *asLong = a; } |
|
66 void setValue (char const& a) { *asChar = a; } |
|
67 } _ptr; |
45 |
68 |
46 public: |
69 public: |
47 template<typename T> |
70 template<typename T> |
48 CommandLineOption (T& data, char shortform, const char* longform, const char* description) : |
71 CommandLineOption (T& data, char shortform, const char* longform, const char* description) : |
49 _shortform (shortform), |
72 _shortform (shortform), |
97 { |
120 { |
98 return &typeid(T) == _type; |
121 return &typeid(T) == _type; |
99 } |
122 } |
100 |
123 |
101 virtual void handleValue (String const& a); |
124 virtual void handleValue (String const& a); |
|
125 virtual String describeArgument() const; |
|
126 virtual String describeExtra() const { return ""; } |
102 }; |
127 }; |
103 |
128 |
|
129 // _________________________________________________________________________________________________ |
|
130 // |
104 template<typename T> |
131 template<typename T> |
105 class EnumeratedCommandLineOption : public CommandLineOption |
132 class EnumeratedCommandLineOption : public CommandLineOption |
106 { |
133 { |
107 StringList _values; |
134 StringList _values; |
108 |
135 |
109 public: |
136 public: |
|
137 using ValueType = typename std::underlying_type<T>::type; |
|
138 |
110 EnumeratedCommandLineOption (T& data, char shortform, const char* longform, |
139 EnumeratedCommandLineOption (T& data, char shortform, const char* longform, |
111 const char* description) : |
140 const char* description) : |
112 CommandLineOption (data, shortform, longform, description) |
141 CommandLineOption (reinterpret_cast<ValueType&> (data), shortform, |
113 { |
142 longform, description) |
|
143 { |
|
144 // Store values |
114 for (int i = 0; i < int (T::NumValues); ++i) |
145 for (int i = 0; i < int (T::NumValues); ++i) |
115 { |
146 { |
116 String value = MakeFormatArgument (T (i)).toLowercase(); |
147 String value = MakeFormatArgument (T (i)).toLowercase(); |
117 int pos; |
148 int pos; |
118 |
149 |
125 |
156 |
126 virtual void handleValue (String const& value) override |
157 virtual void handleValue (String const& value) override |
127 { |
158 { |
128 String const lowvalue (value.toLowercase()); |
159 String const lowvalue (value.toLowercase()); |
129 |
160 |
130 for (int i = 0; i < _values.size(); ++i) |
161 for (ValueType i = 0; i < _values.size(); ++i) |
131 { |
162 { |
132 if (_values[i].toLowercase() == lowvalue) |
163 if (_values[i] == lowvalue) |
133 { |
164 { |
134 *reinterpret_cast<T*> (pointer()) = T (i); |
165 pointer().setValue (i); |
135 return; |
166 return; |
136 } |
167 } |
137 } |
168 } |
138 |
169 |
139 error ("bad value passed to %1 (%2), valid values are: %3", describe(), value, _values); |
170 error ("bad value passed to %1 (%2), valid values are: %3", describe(), value, _values); |
|
171 } |
|
172 |
|
173 virtual String describeArgument() const |
|
174 { |
|
175 return "ENUM"; |
|
176 } |
|
177 |
|
178 StringList const& validValues() const |
|
179 { |
|
180 return _values; |
|
181 } |
|
182 |
|
183 virtual String describeExtra() const |
|
184 { |
|
185 return format ("Valid values for %1: %2", describe(), validValues()); |
140 } |
186 } |
141 }; |
187 }; |
142 |
188 |
143 // _________________________________________________________________________________________________ |
189 // _________________________________________________________________________________________________ |
144 // |
190 // |
151 CommandLine() = default; |
197 CommandLine() = default; |
152 ~CommandLine(); |
198 ~CommandLine(); |
153 template<typename Enum> |
199 template<typename Enum> |
154 void addEnumeratedOption (Enum& e, char shortform, const char* longform, |
200 void addEnumeratedOption (Enum& e, char shortform, const char* longform, |
155 const char* description); |
201 const char* description); |
156 void addOption (CommandLineOption* option); |
202 String describeOptions() const; |
157 StringList process (int argc, char* argv[]); |
203 StringList process (const int argc, char* argv[]); |
158 |
204 |
159 template<typename... Args> |
205 template<typename... Args> |
160 void addOption (Args... args) |
206 void addOption (Args&&... args) |
161 { |
207 { |
162 addOption (new CommandLineOption (args...)); |
208 _options << new CommandLineOption (args...); |
163 } |
209 } |
164 }; |
210 }; |
165 |
211 |
166 // _________________________________________________________________________________________________ |
212 // _________________________________________________________________________________________________ |
167 // |
213 // |
168 template<typename Enum> |
214 template<typename Enum> |
169 void CommandLine::addEnumeratedOption (Enum& e, char shortform, const char* longform, |
215 void CommandLine::addEnumeratedOption (Enum& e, char shortform, const char* longform, |
170 const char* description) |
216 const char* description) |
171 { |
217 { |
172 static_assert(std::is_enum<Enum>::value, "addEnumeratedOption requires a named enumerator"); |
218 static_assert(std::is_enum<Enum>::value, "addEnumeratedOption requires a named enumerator"); |
173 auto enumoption = new EnumeratedCommandLineOption<Enum> (e, shortform, longform, |
219 _options << new EnumeratedCommandLineOption<Enum> (e, shortform, longform, |
174 description); |
220 description); |
175 addOption (static_cast<CommandLineOption*> (enumoption)); |
|
176 } |
221 } |