MXVK Vulkan Framework 0.24.0
C++20 Vulkan rendering framework for practical 2D and 3D application development with SDL3.
Loading...
Searching...
No Matches
Argz< String > Class Template Reference

Template command-line argument parser. More...

#include <mxvk/include/mxvk/argz.hpp>

Public Member Functions

Argz< String > & addOptionDouble (const int &code, const String &value, const String &description)
 Register a flag-only long option (e.g.
Argz< String > & addOptionDoubleValue (const int &code, const String &value, const String &description)
 Register a long option that requires a value argument (e.g.
Argz< String > & addOptionSingle (const int &c, const String &description)
 Register a flag-only short option (e.g.
Argz< String > & addOptionSingleValue (const int &c, const String &description)
 Register a short option that requires a value argument (e.g.
 Argz ()=default
 Argz (Argz< String > &&a)
 Argz (const Argz< String > &a)
 Argz (int argc, char **argv)
 Construct and immediately ingest argv.
const size_t count () const
template<typename T>
void help (T &cout)
 Print all registered options to any ostream-like object.
Argz< String > & initArgs (int argc, char **argv)
 Ingest argc/argv, converting to the target String type.
int lookUpCode (const String &value) const
 Look up the integer code registered for a long option name.
Argz< String > & operator= (Argz< String > &&a)
Argz< String > & operator= (const Argz< String > &a)
int proc (Argument< String > &a)
 Advance the cursor and parse the next argument.
void reset ()
 Reset the internal parse cursor to the beginning of argv.
 ~Argz ()=default

Protected Attributes

ArgumentData< String > arg_data
std::unordered_map< int, Argument< String > > arg_info

Detailed Description

template<StringType String>
class Argz< String >

Template command-line argument parser.

Template Parameters
StringString type satisfying StringType (usually std::string or std::wstring).

Options are registered with addOption*() before parsing. Call proc() in a loop until it returns -1 to iterate over all arguments.

Definition at line 197 of file argz.hpp.

Constructor & Destructor Documentation

◆ ~Argz()

template<StringType String>
Argz< String >::~Argz ( )
default

◆ Argz() [1/4]

template<StringType String>
Argz< String >::Argz ( )
default

◆ Argz() [2/4]

template<StringType String>
Argz< String >::Argz ( int argc,
char ** argv )
inline

Construct and immediately ingest argv.

Parameters
argcArgument count from main().
argvArgument vector from main().

Definition at line 207 of file argz.hpp.

207{ initArgs(argc, argv); }
Template command-line argument parser.
Definition argz.hpp:197
Argz< String > & initArgs(int argc, char **argv)
Ingest argc/argv, converting to the target String type.
Definition argz.hpp:240

◆ Argz() [3/4]

template<StringType String>
Argz< String >::Argz ( const Argz< String > & a)
inline

Definition at line 208 of file argz.hpp.

208: arg_data{a.arg_data}, arg_info{a.arg_info}, index{a.index}, cindex{a.cindex} {}
std::unordered_map< int, Argument< String > > arg_info
Definition argz.hpp:581
ArgumentData< String > arg_data
Definition argz.hpp:580

◆ Argz() [4/4]

template<StringType String>
Argz< String >::Argz ( Argz< String > && a)
inline

Definition at line 221 of file argz.hpp.

221: arg_data{std::move(a.arg_data)}, arg_info{std::move(a.arg_info)}, index{a.index}, cindex{a.cindex} {}

Member Function Documentation

◆ addOptionDouble()

template<StringType String>
Argz< String > & Argz< String >::addOptionDouble ( const int & code,
const String & value,
const String & description )
inline

Register a flag-only long option (e.g.

--verbose).

Parameters
codeUnique integer code associated with this option.
valueLong option name string (without --).
descriptionHelp text.
Returns
Reference to *this for chaining.

Definition at line 315 of file argz.hpp.

315 {
317 a.arg_letter = code;
318 a.arg_type = ArgType::ARG_DOUBLE;
319 a.desc = description;
320 a.arg_name = value;
321 arg_info[code] = a;
322 return *this;
323 }

◆ addOptionDoubleValue()

template<StringType String>
Argz< String > & Argz< String >::addOptionDoubleValue ( const int & code,
const String & value,
const String & description )
inline

Register a long option that requires a value argument (e.g.

--output file).

Parameters
codeUnique integer code.
valueLong option name string.
descriptionHelp text.
Returns
Reference to *this for chaining.

Definition at line 332 of file argz.hpp.

332 {
334 a.arg_letter = code;
335 a.arg_type = ArgType::ARG_DOUBLE_VALUE;
336 a.desc = description;
337 a.arg_name = value;
338 arg_info[code] = a;
339 return *this;
340 }

◆ addOptionSingle()

template<StringType String>
Argz< String > & Argz< String >::addOptionSingle ( const int & c,
const String & description )
inline

Register a flag-only short option (e.g.

-v, -h).

Parameters
cShort option character code.
descriptionHelp text.
Returns
Reference to *this for chaining.

Definition at line 284 of file argz.hpp.

284 {
286 a.arg_letter = c;
287 a.arg_type = ArgType::ARG_SINGLE;
288 a.desc = description;
289 arg_info[c] = a;
290 return *this;
291 }

◆ addOptionSingleValue()

template<StringType String>
Argz< String > & Argz< String >::addOptionSingleValue ( const int & c,
const String & description )
inline

Register a short option that requires a value argument (e.g.

-o file).

Parameters
cShort option character code.
descriptionHelp text.
Returns
Reference to *this for chaining.

Definition at line 299 of file argz.hpp.

299 {
301 a.arg_letter = c;
302 a.arg_type = ArgType::ARG_SINGLE_VALUE;
303 a.desc = description;
304 arg_info[c] = a;
305 return *this;
306 }

◆ count()

template<StringType String>
const size_t Argz< String >::count ( ) const
inline
Returns
Number of argv entries consumed so far.

Definition at line 577 of file argz.hpp.

577{ return index; }

◆ help()

template<StringType String>
template<typename T>
void Argz< String >::help ( T & cout)
inline

Print all registered options to any ostream-like object.

Template Parameters
TOutput stream type (e.g. std::ostream, std::wostream).
Parameters
coutDestination stream.

Definition at line 506 of file argz.hpp.

506 {
508 const bool use_color = supportsColor(cout);
509 auto write_ansi = [&](const char *seq) {
510 if (!use_color) {
511 return;
512 }
513 if constexpr (std::is_same_v<char_type, char>) {
514 cout << seq;
515 } else if constexpr (std::is_same_v<char_type, wchar_t>) {
516 for (const char *p = seq; *p != '\0'; ++p) {
518 }
519 }
520 };
521 auto write_padding = [&](size_t count) {
522 for (size_t i = 0; i < count; ++i) {
524 }
525 };
526 struct HelpRow {
528 String desc;
529 bool is_short;
530 };
533 for (const auto &i : arg_info) {
534 if (i.second.arg_type == ArgType::ARG_SINGLE || i.second.arg_type == ArgType::ARG_SINGLE_VALUE)
535 v.push_back(i.second);
536 else if (i.second.arg_type == ArgType::ARG_DOUBLE || i.second.arg_type == ArgType::ARG_DOUBLE_VALUE)
537 v2.push_back(i.second);
538 }
542 rows.reserve(v.size() + v2.size());
543 for (const auto &a : v) {
545 token += static_cast<char_type>('-');
546 token += static_cast<char_type>(a.arg_letter);
547 rows.push_back(HelpRow{std::move(token), a.desc, true});
548 }
549 for (const auto &a : v2) {
551 token += static_cast<char_type>('-');
552 token += static_cast<char_type>('-');
553 token += a.arg_name;
554 rows.push_back(HelpRow{std::move(token), a.desc, false});
555 }
556 size_t token_width = 0;
557 for (const auto &row : rows) {
558 token_width = std::max(token_width, static_cast<size_t>(row.token.length()));
559 }
560 const size_t desc_column = token_width + 2;
561 for (const auto &row : rows) {
562 write_ansi(row.is_short ? "\x1b[1;36m" : "\x1b[1;35m");
563 cout << row.token;
564 write_ansi("\x1b[0m");
565 if (desc_column > row.token.length()) {
566 write_padding(desc_column - row.token.length());
567 } else {
568 write_padding(2);
569 }
570 write_ansi("\x1b[90m");
571 cout << row.desc;
572 write_ansi("\x1b[0m");
573 cout << '\n';
574 }
575 }
const size_t count() const
Definition argz.hpp:577

◆ initArgs()

template<StringType String>
Argz< String > & Argz< String >::initArgs ( int argc,
char ** argv )
inline

Ingest argc/argv, converting to the target String type.

Parameters
argcArgument count.
argvArgument vector.
Returns
Reference to *this for method chaining.

Definition at line 240 of file argz.hpp.

240 {
241 arg_data.argc = argc;
242 arg_data.args.clear();
243 if (argc > 1) {
244 arg_data.args.reserve(static_cast<size_t>(argc - 1));
245 }
247 for (int i = 1; i < argc; ++i) {
248 const char *a = (argv != nullptr) ? argv[i] : nullptr;
249 arg_data.args.emplace_back(a != nullptr ? a : "");
250 }
251 reset();
252 return *this;
253 }
255 for (int i = 1; i < argc; ++i) {
256 const char *a = (argv != nullptr) ? argv[i] : nullptr;
257 String data;
258 if (a != nullptr) {
259 for (size_t z = 0; a[z] != 0; ++z) {
260 data += static_cast<typename String::value_type>(a[z]);
261 }
262 }
263 arg_data.args.push_back(data);
264 }
265 reset();
266 return *this;
267 }
268 reset();
269 return *this;
270 }
void reset()
Reset the internal parse cursor to the beginning of argv.
Definition argz.hpp:273

◆ lookUpCode()

template<StringType String>
int Argz< String >::lookUpCode ( const String & value) const
inline

Look up the integer code registered for a long option name.

Parameters
valueLong option name (without --).
Returns
The registered code, or -1 if not found.

Definition at line 347 of file argz.hpp.

347 {
348 for (const auto &i : arg_info) {
349 if (i.second.arg_name == value) {
350 return i.second.arg_letter;
351 }
352 }
353 return -1;
354 }

◆ operator=() [1/2]

template<StringType String>
Argz< String > & Argz< String >::operator= ( Argz< String > && a)
inline

Definition at line 223 of file argz.hpp.

223 {
224 if (this == &a) {
225 return *this;
226 }
229 index = a.index;
230 cindex = a.cindex;
231 return *this;
232 }

◆ operator=() [2/2]

template<StringType String>
Argz< String > & Argz< String >::operator= ( const Argz< String > & a)
inline

Definition at line 210 of file argz.hpp.

210 {
211 if (this == &a) {
212 return *this;
213 }
216 index = a.index;
217 cindex = a.cindex;
218 return *this;
219 }

◆ proc()

template<StringType String>
int Argz< String >::proc ( Argument< String > & a)
inline

Advance the cursor and parse the next argument.

Parameters
aOutput: filled with the matched option details.
Returns
The option code on success; '-' for a positional argument; -1 when exhausted.
Exceptions
ArgException<String>On unrecognised options or missing values.

Definition at line 362 of file argz.hpp.

362 {
363 if (index < static_cast<int>(arg_data.args.size())) {
364 const String &type{arg_data.args[index]};
365 if (type.length() > 2 && type[0] == '-' && type[1] == '-') {
366 String name{};
368 const auto eq_pos = type.find(static_cast<typename String::value_type>('='));
369 const bool has_inline_value = (eq_pos != String::npos);
370 for (size_t z = 2; z < type.length(); ++z)
371 if (!has_inline_value || z < eq_pos) {
372 name += type[z];
373 } else if (z > eq_pos) {
374 inline_value += type[z];
375 }
376 int code = lookUpCode(name);
377 if (code != -1) {
378 auto pos = arg_info.find(code);
379 if (pos != arg_info.end()) {
380 if (pos->second.arg_type == ArgType::ARG_DOUBLE) {
381 if (has_inline_value) {
383 throw ArgException<String>("Invalid switch not found!");
384 }
386 throw ArgException<String>(L"Invalid switch not found!");
387 }
388 }
389 a = pos->second;
390 a.arg_name = name;
391 index++;
392 return code;
393 } else {
394 a = pos->second;
395 a.arg_name = name;
396 if (has_inline_value) {
397 if (inline_value.empty()) {
399 throw ArgException<String>("Expected Value");
400 }
402 throw ArgException<String>(L"Expected Value");
403 }
404 }
405 a.arg_value = inline_value;
406 index++;
407 return code;
408 }
409 if (++index < static_cast<int>(arg_data.args.size())) {
410 const String &s{arg_data.args[index]};
411 if (canUseAsOptionValue(s)) {
412 a.arg_name = name;
413 a.arg_value = s;
414 index++;
415 return code;
416 }
417 }
419 throw ArgException<String>("Expected Value");
420 }
422 throw ArgException<String>(L"Expected Value");
423 }
424 }
425 }
426 } else {
427 throwUnknownOption(type);
428 }
429 } else if (type.length() == 1 && type[0] == '-') {
431 throw ArgException<String>("Expected Value found -");
432 }
434 throw ArgException<String>(L"Expected Value found -");
435 }
436 } else if (type.length() > 1 && (type[0] == '-')) {
437 const int c{type[cindex]};
438 const auto pos{arg_info.find(c)};
439 cindex++;
440 if (cindex >= static_cast<int>(type.length())) {
441 cindex = 1;
442 index++;
443 }
445 name_val += static_cast<typename String::value_type>(c);
446 if (pos != arg_info.end()) {
447 if (pos->second.arg_type == ArgType::ARG_SINGLE) {
448 a = pos->second;
449 a.arg_name = name_val;
450 return c;
451 } else if (pos->second.arg_type == ArgType::ARG_SINGLE_VALUE) {
452 if (index < static_cast<int>(arg_data.args.size())) {
453 const String &s{arg_data.args[index]};
454 if (!canUseAsOptionValue(s)) {
456 throw ArgException<String>("Expected Value found -");
457 }
459 throw ArgException<String>(L"Expected Value found -");
460 }
461 }
462 if (s.length() > 0) {
463 a = pos->second;
464 a.arg_value = s;
465 a.arg_name = name_val;
466 index++;
467 return c;
468 }
469 } else {
471 throw ArgException<String>("Expected Value");
472 }
474 throw ArgException<String>(L"Expected Value");
475 }
476 }
477 } else {
479 throw ArgException<String>("Invalid switch not found!");
480 }
482 throw ArgException<String>(L"Invalid switch not found!");
483 }
484 }
485 } else {
486 throwUnknownOption(type);
487 }
488 } else {
490 a.arg_name = String{};
491 a.arg_type = ArgType::ARG_NONE;
492 a.arg_name = a.arg_value = arg_data.args.at(index);
493 index++;
494 return '-';
495 }
496 }
497 return -1;
498 }
int lookUpCode(const String &value) const
Look up the integer code registered for a long option name.
Definition argz.hpp:347

◆ reset()

template<StringType String>
void Argz< String >::reset ( )
inline

Reset the internal parse cursor to the beginning of argv.

Definition at line 273 of file argz.hpp.

273 {
274 index = 0;
275 cindex = 1;
276 }

Member Data Documentation

◆ arg_data

template<StringType String>
ArgumentData<String> Argz< String >::arg_data
protected

Definition at line 580 of file argz.hpp.

◆ arg_info

template<StringType String>
std::unordered_map<int, Argument<String> > Argz< String >::arg_info
protected

Definition at line 581 of file argz.hpp.


The documentation for this class was generated from the following file: