Halide 22.0.0 Halide compiler and libraries

Loading...
Searching...
No Matches
cmdline.h
Go to the documentation of this file.
1// GitHub source: from https://github.com/tanakh/cmdline
2// Modifications made in-place to remove the use of exceptions,
3// flagged with HALIDE_WITH_EXCEPTIONS
4
5/*
6 Copyright (c) 2009, Hideyuki Tanaka
7 All rights reserved.
8
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions are met:
11 * Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13 * Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
16 * Neither the name of the <organization> nor the
17 names of its contributors may be used to endorse or promote products
18 derived from this software without specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY <copyright holder> ''AS IS'' AND ANY
21 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
24 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30*/
31
32#pragma once
33
34#include <algorithm>
35#include <cstdlib>
36#include <cstring>
37#include <iostream>
38#include <map>
39#include <sstream>
40#include <stdexcept>
41#include <string>
42#include <typeinfo>
43#include <vector>
44
45#if defined(_MSC_VER) && !defined(NOMINMAX)
46#define NOMINMAX
47#endif
48
49#if !defined(_WIN32)
50#include <cxxabi.h>
51#else
52#include <windows.h>
53#pragma warning(disable : 4091)
54#include <dbghelp.h>
55#pragma comment(lib, "dbghelp.lib")
56#endif
57
58 namespace cmdline {
59
60 namespace detail {
61
62#ifdef HALIDE_WITH_EXCEPTIONS
63 inline void throw_bad_cast() {
64 throw std::bad_cast();
65}
66#else
67 inline void throw_bad_cast() {
68 std::cerr << "bad cast\n";
69 exit(1);
70}
71#endif
72
73 template<typename Target, typename Source, bool Same>
74 class lexical_cast_t {
75 public:
76 static Target cast(const Source &arg) {
77 Target ret;
78 std::stringstream ss;
79 if (!(ss << arg && ss >> ret && ss.eof())) {
80 throw_bad_cast();
81 }
82
83 return ret;
84 }
85};
86
87 template<typename Target, typename Source>
88 class lexical_cast_t<Target, Source, true> {
89 public:
90 static Target cast(const Source &arg) {
91 return arg;
92 }
93};
94
95 template<typename Source>
96 class lexical_cast_t<std::string, Source, false> {
97 public:
98 static std::string cast(const Source &arg) {
99 std::ostringstream ss;
100 ss << arg;
101 return ss.str();
102 }
103};
104
105 template<typename Target>
106 class lexical_cast_t<Target, std::string, false> {
107 public:
108 static Target cast(const std::string &arg) {
109 Target ret;
110 std::istringstream ss(arg);
111 if (!(ss >> ret && ss.eof())) {
112 throw_bad_cast();
113 }
114 return ret;
115 }
116};
117
118 template<typename T1, typename T2>
119 struct is_same {
120 static const bool value = false;
121};
122
123 template<typename T>
124 struct is_same<T, T> {
125 static const bool value = true;
126};
127
128 template<typename Target, typename Source>
129Target lexical_cast(const Source &arg) {
130 return lexical_cast_t<Target, Source, detail::is_same<Target, Source>::value>::cast(arg);
131}
132
133 static inline std::string demangle(const std::string &name) {
134#if !defined(_WIN32)
135 int status = 0;
136 char *p = abi::__cxa_demangle(name.c_str(), nullptr, nullptr, &status);
137 std::string ret(p);
138 free(p);
139 return ret;
140#else
141 char demangled_name[8192];
142 if (UnDecorateSymbolName(name.c_str(), demangled_name, sizeof(demangled_name),
143 UNDNAME_COMPLETE)) {
144 std::string ret(demangled_name);
145 return ret;
146 } else {
147 DWORD error = GetLastError();
148 std::cout << "UnDecorateSymbolName error: " << error << std::endl;
149 return name;
150 }
151#endif
152}
153
154 template<class T>
155std::string readable_typename() {
156#ifndef HALIDE_ENABLE_RTTI
157 return "unrecognized type";
158#else
159 return demangle(typeid(T).name());
160#endif
161}
162
163 template<class T>
164std::string default_value(const T &def) {
165 return detail::lexical_cast<std::string>(def);
166}
167
168 template<>
169 inline std::string readable_typename<std::string>() {
170 return "string";
171}
172
173#ifndef HALIDE_ENABLE_RTTI
174 template<>
175 inline std::string readable_typename<bool>() {
176 return "bool";
177}
178
179 template<>
180 inline std::string readable_typename<int>() {
181 return "int";
182}
183#endif
184
185} // namespace detail
186
187//-----
188
189#ifdef HALIDE_WITH_EXCEPTIONS
190 class cmdline_error : public std::exception {
191 public:
192 explicit cmdline_error(const std::string &msg)
193 : msg(msg) {
194 }
195 ~cmdline_error() throw() override = default;
196 const char *what() const throw() override {
197 return msg.c_str();
198 }
199
200 private:
201 std::string msg;
202};
203 inline void throw_cmdline_error(const std::string &s) {
204 throw cmdline::cmdline_error(s);
205}
206#else
207 inline void throw_cmdline_error(const std::string &s) {
208 std::cerr << "error: " << s << "\n";
209 exit(1);
210}
211#endif
212
213 template<class T>
214 struct default_reader {
215 T operator()(const std::string &str) {
216 return detail::lexical_cast<T>(str);
217 }
218};
219
220 template<class T>
221 struct range_reader {
222 range_reader(const T &low, const T &high)
223 : low(low), high(high) {
224 }
225 T operator()(const std::string &s) const {
226 T ret = default_reader<T>()(s);
227 if (!(ret >= low && ret <= high)) {
228 throw_cmdline_error("range_error");
229 }
230 return ret;
231 }
232
233 private:
234 T low, high;
235};
236
237 template<class T>
238 range_reader<T> range(const T &low, const T &high) {
239 return range_reader<T>(low, high);
240}
241
242 template<class T>
243 struct oneof_reader {
244 T operator()(const std::string &s) {
245 T ret = default_reader<T>()(s);
246 if (std::find(alt.begin(), alt.end(), ret) == alt.end()) {
247 throw_cmdline_error("");
248 }
249 return ret;
250 }
251 void add(const T &v) {
252 alt.push_back(v);
253 }
254
255 private:
256 std::vector<T> alt;
257};
258
259 template<class T>
260 oneof_reader<T> oneof(T a1) {
261 oneof_reader<T> ret;
262 ret.add(a1);
263 return ret;
264}
265
266 template<class T>
267 oneof_reader<T> oneof(T a1, T a2) {
268 oneof_reader<T> ret;
269 ret.add(a1);
270 ret.add(a2);
271 return ret;
272}
273
274 template<class T>
275 oneof_reader<T> oneof(T a1, T a2, T a3) {
276 oneof_reader<T> ret;
277 ret.add(a1);
278 ret.add(a2);
279 ret.add(a3);
280 return ret;
281}
282
283 template<class T>
284 oneof_reader<T> oneof(T a1, T a2, T a3, T a4) {
285 oneof_reader<T> ret;
286 ret.add(a1);
287 ret.add(a2);
288 ret.add(a3);
289 ret.add(a4);
290 return ret;
291}
292
293 template<class T>
294 oneof_reader<T> oneof(T a1, T a2, T a3, T a4, T a5) {
295 oneof_reader<T> ret;
296 ret.add(a1);
297 ret.add(a2);
298 ret.add(a3);
299 ret.add(a4);
300 ret.add(a5);
301 return ret;
302}
303
304 template<class T>
305 oneof_reader<T> oneof(T a1, T a2, T a3, T a4, T a5, T a6) {
306 oneof_reader<T> ret;
307 ret.add(a1);
308 ret.add(a2);
309 ret.add(a3);
310 ret.add(a4);
311 ret.add(a5);
312 ret.add(a6);
313 return ret;
314}
315
316 template<class T>
317 oneof_reader<T> oneof(T a1, T a2, T a3, T a4, T a5, T a6, T a7) {
318 oneof_reader<T> ret;
319 ret.add(a1);
320 ret.add(a2);
321 ret.add(a3);
322 ret.add(a4);
323 ret.add(a5);
324 ret.add(a6);
325 ret.add(a7);
326 return ret;
327}
328
329 template<class T>
330 oneof_reader<T> oneof(T a1, T a2, T a3, T a4, T a5, T a6, T a7, T a8) {
331 oneof_reader<T> ret;
332 ret.add(a1);
333 ret.add(a2);
334 ret.add(a3);
335 ret.add(a4);
336 ret.add(a5);
337 ret.add(a6);
338 ret.add(a7);
339 ret.add(a8);
340 return ret;
341}
342
343 template<class T>
344 oneof_reader<T> oneof(T a1, T a2, T a3, T a4, T a5, T a6, T a7, T a8, T a9) {
345 oneof_reader<T> ret;
346 ret.add(a1);
347 ret.add(a2);
348 ret.add(a3);
349 ret.add(a4);
350 ret.add(a5);
351 ret.add(a6);
352 ret.add(a7);
353 ret.add(a8);
354 ret.add(a9);
355 return ret;
356}
357
358 template<class T>
359 oneof_reader<T> oneof(T a1, T a2, T a3, T a4, T a5, T a6, T a7, T a8, T a9, T a10) {
360 oneof_reader<T> ret;
361 ret.add(a1);
362 ret.add(a2);
363 ret.add(a3);
364 ret.add(a4);
365 ret.add(a5);
366 ret.add(a6);
367 ret.add(a7);
368 ret.add(a8);
369 ret.add(a9);
370 ret.add(a10);
371 return ret;
372}
373
374//-----
375
376 class parser {
377 public:
378 parser() = default;
379 ~parser() {
380 for (auto &option : options) {
381 delete option.second;
382 }
383 }
384
385 void add(const std::string &name,
386 char short_name = 0,
387 const std::string &desc = "") {
388 if (options.count(name)) {
389 throw_cmdline_error("multiple definition: " + name);
390 }
391 options[name] = new option_without_value(name, short_name, desc);
392 ordered.push_back(options[name]);
393 }
394
395 template<class T>
396 void add(const std::string &name,
397 char short_name = 0,
398 const std::string &desc = "",
399 bool need = true,
400 const T &def = T()) {
401 add(name, short_name, desc, need, def, default_reader<T>());
402 }
403
404 template<class T, class F>
405 void add(const std::string &name,
406 char short_name = 0,
407 const std::string &desc = "",
408 bool need = true,
409 const T &def = T(),
410 F reader = F()) {
411 if (options.count(name)) {
412 throw_cmdline_error("multiple definition: " + name);
413 }
414 options[name] = new option_with_value_with_reader<T, F>(name, short_name, need, def, desc, reader);
415 ordered.push_back(options[name]);
416 }
417
418 void footer(const std::string &f) {
419 ftr = f;
420 }
421
422 void set_program_name(const std::string &name) {
423 prog_name = name;
424 }
425
426 bool exist(const std::string &name) const {
427 if (options.count(name) == 0) {
428 throw_cmdline_error("there is no flag: --" + name);
429 }
430 return options.find(name)->second->has_set();
431 }
432
433 template<class T>
434 const T &get(const std::string &name) const {
435 if (options.count(name) == 0) {
436 throw_cmdline_error("there is no flag: --" + name);
437 }
438#ifndef HALIDE_ENABLE_RTTI
439 const option_with_value<T> *p = reinterpret_cast<const option_with_value<T> *>(options.find(name)->second);
440 return p->get();
441#else
442 const option_with_value<T> *p = dynamic_cast<const option_with_value<T> *>(options.find(name)->second);
443 if (p == nullptr) {
444 throw_cmdline_error("type mismatch flag '" + name + "'");
445 }
446 return p->get();
447#endif
448 }
449
450 const std::vector<std::string> &rest() const {
451 return others;
452 }
453
454 bool parse(const std::string &arg) {
455 std::vector<std::string> args;
456
457 std::string buf;
458 bool in_quote = false;
459 for (std::string::size_type i = 0; i < arg.length(); i++) {
460 if (arg[i] == '\"') {
461 in_quote = !in_quote;
462 continue;
463 }
464
465 if (arg[i] == ' ' && !in_quote) {
466 args.push_back(buf);
467 buf = "";
468 continue;
469 }
470
471 if (arg[i] == '\\') {
472 i++;
473 if (i >= arg.length()) {
474 errors.emplace_back("unexpected occurrence of '\\' at end of string");
475 return false;
476 }
477 }
478
479 buf += arg[i];
480 }
481
482 if (in_quote) {
483 errors.emplace_back("quote is not closed");
484 return false;
485 }
486
487 if (!buf.empty()) {
488 args.push_back(buf);
489 }
490
491 for (auto &arg : args) {
492 std::cout << "\"" << arg << "\"\n";
493 }
494
495 return parse(args);
496 }
497
498 bool parse(const std::vector<std::string> &args) {
499 int argc = static_cast<int>(args.size());
500 std::vector<const char *> argv(argc);
501
502 for (int i = 0; i < argc; i++) {
503 argv[i] = args[i].c_str();
504 }
505
506 return parse(argc, &argv[0]);
507 }
508
509 bool parse(int argc, const char *const argv[]) {
510 errors.clear();
511 others.clear();
512
513 if (argc < 1) {
514 errors.emplace_back("argument number must be longer than 0");
515 return false;
516 }
517 if (prog_name.empty()) {
518 prog_name = argv[0];
519 }
520
521 std::map<char, std::string> lookup;
522 for (auto &option : options) {
523 if (option.first.empty()) {
524 continue;
525 }
526 char initial = option.second->short_name();
527 if (initial) {
528 if (lookup.count(initial) > 0) {
529 lookup[initial] = "";
530 errors.push_back(std::string("short option '") + initial + "' is ambiguous");
531 return false;
532 } else {
533 lookup[initial] = option.first;
534 }
535 }
536 }
537
538 for (int i = 1; i < argc; i++) {
539 if (strncmp(argv[i], "--", 2) == 0) {
540 const char *p = strchr(argv[i] + 2, '=');
541 if (p) {
542 std::string name(argv[i] + 2, p);
543 std::string val(p + 1);
544 set_option(name, val);
545 } else {
546 std::string name(argv[i] + 2);
547 if (options.count(name) == 0) {
548 errors.push_back("undefined option: --" + name);
549 continue;
550 }
551 if (options[name]->has_value()) {
552 if (i + 1 >= argc) {
553 errors.push_back("option needs value: --" + name);
554 continue;
555 } else {
556 i++;
557 set_option(name, argv[i]);
558 }
559 } else {
560 set_option(name);
561 }
562 }
563 } else if (strncmp(argv[i], "-", 1) == 0) {
564 if (!argv[i][1]) {
565 continue;
566 }
567 char last = argv[i][1];
568 for (int j = 2; argv[i][j]; j++) {
569 last = argv[i][j];
570 if (lookup.count(argv[i][j - 1]) == 0) {
571 errors.push_back(std::string("undefined short option: -") + argv[i][j - 1]);
572 continue;
573 }
574 if (lookup[argv[i][j - 1]].empty()) {
575 errors.push_back(std::string("ambiguous short option: -") + argv[i][j - 1]);
576 continue;
577 }
578 set_option(lookup[argv[i][j - 1]]);
579 }
580
581 if (lookup.count(last) == 0) {
582 errors.push_back(std::string("undefined short option: -") + last);
583 continue;
584 }
585 if (lookup[last].empty()) {
586 errors.push_back(std::string("ambiguous short option: -") + last);
587 continue;
588 }
589
590 if (i + 1 < argc && options[lookup[last]]->has_value()) {
591 set_option(lookup[last], argv[i + 1]);
592 i++;
593 } else {
594 set_option(lookup[last]);
595 }
596 } else {
597 others.emplace_back(argv[i]);
598 }
599 }
600
601 for (auto &option : options) {
602 if (!option.second->valid()) {
603 errors.push_back("need option: --" + std::string(option.first));
604 }
605 }
606
607 return errors.empty();
608 }
609
610 void parse_check(const std::string &arg) {
611 if (!options.count("help")) {
612 add("help", '?', "print this message");
613 }
614 check(0, parse(arg));
615 }
616
617 void parse_check(const std::vector<std::string> &args) {
618 if (!options.count("help")) {
619 add("help", '?', "print this message");
620 }
621 check(args.size(), parse(args));
622 }
623
624 void parse_check(int argc, char *argv[]) {
625 if (!options.count("help")) {
626 add("help", '?', "print this message");
627 }
628 check(argc, parse(argc, argv));
629 }
630
631 std::string error() const {
632 return !errors.empty() ? errors[0] : "";
633 }
634
635 std::string error_full() const {
636 std::ostringstream oss;
637 for (const auto &error : errors) {
638 oss << error << "\n";
639 }
640 return oss.str();
641 }
642
643 std::string usage() const {
644 std::ostringstream oss;
645 oss << "usage: " << prog_name << " ";
646 for (const auto &o : ordered) {
647 if (o->must()) {
648 oss << o->short_description() << " ";
649 }
650 }
651
652 oss << "[options] ... " << ftr << "\n";
653 oss << "options:\n";
654
655 size_t max_width = 0;
656 for (const auto &o : ordered) {
657 max_width = std::max(max_width, o->name().length());
658 }
659 for (const auto &o : ordered) {
660 if (o->short_name()) {
661 oss << " -" << o->short_name() << ", ";
662 } else {
663 oss << " ";
664 }
665
666 oss << "--" << o->name();
667 for (size_t j = o->name().length(); j < max_width + 4; j++) {
668 oss << ' ';
669 }
670 oss << o->description() << "\n";
671 }
672 return oss.str();
673 }
674
675 private:
676 void check(int argc, bool ok) {
677 if ((argc == 1 && !ok) || exist("help")) {
678 std::cerr << usage();
679 exit(0);
680 }
681
682 if (!ok) {
683 std::cerr << error() << "\n"
684 << usage();
685 exit(1);
686 }
687 }
688
689 void set_option(const std::string &name) {
690 if (options.count(name) == 0) {
691 errors.push_back("undefined option: --" + name);
692 return;
693 }
694 if (!options[name]->set()) {
695 errors.push_back("option needs value: --" + name);
696 return;
697 }
698 }
699
700 void set_option(const std::string &name, const std::string &value) {
701 if (options.count(name) == 0) {
702 errors.push_back("undefined option: --" + name);
703 return;
704 }
705 if (!options[name]->set(value)) {
706 errors.push_back("option value is invalid: --" + name + "=" + value);
707 return;
708 }
709 }
710
711 class option_base {
712 public:
713 virtual ~option_base() = default;
714
715 virtual bool has_value() const = 0;
716 virtual bool set() = 0;
717 virtual bool set(const std::string &value) = 0;
718 virtual bool has_set() const = 0;
719 virtual bool valid() const = 0;
720 virtual bool must() const = 0;
721
722 virtual const std::string &name() const = 0;
723 virtual char short_name() const = 0;
724 virtual const std::string &description() const = 0;
725 virtual std::string short_description() const = 0;
726 };
727
728 class option_without_value : public option_base {
729 public:
730 option_without_value(const std::string &name,
731 char short_name,
732 const std::string &desc)
733 : nam(name), snam(short_name), desc(desc) {
734 }
735 ~option_without_value() override = default;
736
737 bool has_value() const override {
738 return false;
739 }
740
741 bool set() override {
742 has = true;
743 return true;
744 }
745
746 bool set(const std::string &) override {
747 return false;
748 }
749
750 bool has_set() const override {
751 return has;
752 }
753
754 bool valid() const override {
755 return true;
756 }
757
758 bool must() const override {
759 return false;
760 }
761
762 const std::string &name() const override {
763 return nam;
764 }
765
766 char short_name() const override {
767 return snam;
768 }
769
770 const std::string &description() const override {
771 return desc;
772 }
773
774 std::string short_description() const override {
775 return "--" + nam;
776 }
777
778 private:
779 std::string nam;
780 char snam;
781 std::string desc;
782 bool has = false;
783 };
784
785 template<class T>
786 class option_with_value : public option_base {
787 public:
788 option_with_value(const std::string &name,
789 char short_name,
790 bool need,
791 const T &def,
792 const std::string &desc)
793 : nam(name), snam(short_name), need(need), def(def), actual(def) {
794 this->desc = full_description(desc);
795 }
796 ~option_with_value() override = default;
797
798 const T &get() const {
799 return actual;
800 }
801
802 bool has_value() const override {
803 return true;
804 }
805
806 bool set() override {
807 return false;
808 }
809
810 bool set(const std::string &value) override {
811#ifdef HALIDE_WITH_EXCEPTIONS
812 try {
813 actual = read(value);
814 has = true;
815 } catch (const std::exception &e) {
816 std::cout << "Exception was caught: " << e.what() << "\n";
817 return false;
818 }
819 return true;
820#else
821 actual = read(value);
822 has = true;
823 return true;
824#endif
825 }
826
827 bool has_set() const override {
828 return has;
829 }
830
831 bool valid() const override {
832 if (need && !has) {
833 return false;
834 }
835 return true;
836 }
837
838 bool must() const override {
839 return need;
840 }
841
842 const std::string &name() const override {
843 return nam;
844 }
845
846 char short_name() const override {
847 return snam;
848 }
849
850 const std::string &description() const override {
851 return desc;
852 }
853
854 std::string short_description() const override {
855 return "--" + nam + "=" + detail::readable_typename<T>();
856 }
857
858 protected:
859 std::string full_description(const std::string &desc) {
860 return desc + " (" + detail::readable_typename<T>() +
861 (need ? "" : " [=" + detail::default_value<T>(def) + "]") + ")";
862 }
863
864 virtual T read(const std::string &s) = 0;
865
866 std::string nam;
867 char snam;
868 bool need;
869 std::string desc;
870
871 bool has = false;
872 T def;
873 T actual;
874 };
875
876 template<class T, class F>
877 class option_with_value_with_reader : public option_with_value<T> {
878 public:
879 option_with_value_with_reader(const std::string &name,
880 char short_name,
881 bool need,
882 const T &def,
883 const std::string &desc,
884 F reader)
885 : option_with_value<T>(name, short_name, need, def, desc), reader(reader) {
886 }
887
888 private:
889 T read(const std::string &s) override {
890 return reader(s);
891 }
892
893 F reader;
894 };
895
896 std::map<std::string, option_base *> options;
897 std::vector<option_base *> ordered;
898 std::string ftr;
899
900 std::string prog_name;
901 std::vector<std::string> others;
902
903 std::vector<std::string> errors;
904};
905
906} // namespace cmdline
cmdline::detail::lexical_cast_t< Target, Source, true >::cast
static Target cast(const Source &arg)
Definition cmdline.h:90
cmdline::detail::lexical_cast_t< Target, std::string, false >::cast
static Target cast(const std::string &arg)
Definition cmdline.h:108
cmdline::detail::lexical_cast_t< std::string, Source, false >::cast
static std::string cast(const Source &arg)
Definition cmdline.h:98
cmdline::detail::lexical_cast_t
Definition cmdline.h:74
cmdline::detail::lexical_cast_t::cast
static Target cast(const Source &arg)
Definition cmdline.h:76
cmdline::parser
Definition cmdline.h:376
cmdline::parser::footer
void footer(const std::string &f)
Definition cmdline.h:418
cmdline::parser::error_full
std::string error_full() const
Definition cmdline.h:635
cmdline::parser::parse_check
void parse_check(const std::vector< std::string > &args)
Definition cmdline.h:617
cmdline::parser::add
void add(const std::string &name, char short_name=0, const std::string &desc="")
Definition cmdline.h:385
cmdline::parser::usage
std::string usage() const
Definition cmdline.h:643
cmdline::parser::get
const T & get(const std::string &name) const
Definition cmdline.h:434
cmdline::parser::add
void add(const std::string &name, char short_name=0, const std::string &desc="", bool need=true, const T &def=T(), F reader=F())
Definition cmdline.h:405
cmdline::parser::parser
parser()=default
cmdline::parser::parse
bool parse(const std::vector< std::string > &args)
Definition cmdline.h:498
cmdline::parser::rest
const std::vector< std::string > & rest() const
Definition cmdline.h:450
cmdline::parser::parse
bool parse(int argc, const char *const argv[])
Definition cmdline.h:509
cmdline::parser::add
void add(const std::string &name, char short_name=0, const std::string &desc="", bool need=true, const T &def=T())
Definition cmdline.h:396
cmdline::parser::error
std::string error() const
Definition cmdline.h:631
cmdline::parser::parse_check
void parse_check(int argc, char *argv[])
Definition cmdline.h:624
cmdline::parser::parse
bool parse(const std::string &arg)
Definition cmdline.h:454
cmdline::parser::exist
bool exist(const std::string &name) const
Definition cmdline.h:426
cmdline::parser::~parser
~parser()
Definition cmdline.h:379
cmdline::parser::parse_check
void parse_check(const std::string &arg)
Definition cmdline.h:610
cmdline::parser::set_program_name
void set_program_name(const std::string &name)
Definition cmdline.h:422
DWORD
unsigned long DWORD
Definition mini_d3d12.h:182
cmdline::detail::readable_typename< int >
std::string readable_typename< int >()
Definition cmdline.h:180
cmdline::detail::lexical_cast
Target lexical_cast(const Source &arg)
Definition cmdline.h:129
cmdline::detail::readable_typename
std::string readable_typename()
Definition cmdline.h:155
cmdline::detail::throw_bad_cast
void throw_bad_cast()
Definition cmdline.h:67
cmdline::detail::readable_typename< bool >
std::string readable_typename< bool >()
Definition cmdline.h:175
cmdline::detail::default_value
std::string default_value(const T &def)
Definition cmdline.h:164
cmdline::detail::readable_typename< std::string >
std::string readable_typename< std::string >()
Definition cmdline.h:169
cmdline
Definition cmdline.h:58
cmdline::oneof
oneof_reader< T > oneof(T a1)
Definition cmdline.h:260
cmdline::range
range_reader< T > range(const T &low, const T &high)
Definition cmdline.h:238
cmdline::throw_cmdline_error
void throw_cmdline_error(const std::string &s)
Definition cmdline.h:207
strchr
const char * strchr(const char *s, int c)
strncmp
int strncmp(const char *s, const char *t, size_t n)
free
void free(void *)
cmdline::default_reader
Definition cmdline.h:214
cmdline::default_reader::operator()
T operator()(const std::string &str)
Definition cmdline.h:215
cmdline::detail::is_same
Definition cmdline.h:119
cmdline::detail::is_same::value
static const bool value
Definition cmdline.h:120
cmdline::oneof_reader
Definition cmdline.h:243
cmdline::oneof_reader::operator()
T operator()(const std::string &s)
Definition cmdline.h:244
cmdline::oneof_reader::add
void add(const T &v)
Definition cmdline.h:251
cmdline::range_reader
Definition cmdline.h:221
cmdline::range_reader::range_reader
range_reader(const T &low, const T &high)
Definition cmdline.h:222
cmdline::range_reader::operator()
T operator()(const std::string &s) const
Definition cmdline.h:225