Halide  12.0.1
Halide compiler and libraries
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>
75 public:
76  static Target cast(const Source &arg) {
77  Target ret;
78  std::stringstream ss;
79  if (!(ss << arg && ss >> ret && ss.eof())) {
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>
129 Target lexical_cast(const Source &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>
155 std::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>
164 std::string default_value(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  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>
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()) {
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>
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;
380  for (std::map<std::string, option_base *>::iterator p = options.begin();
381  p != options.end(); p++) {
382  delete p->second;
383  }
384  }
385 
386  void add(const std::string &name,
387  char short_name = 0,
388  const std::string &desc = "") {
389  if (options.count(name)) {
390  throw_cmdline_error("multiple definition: " + name);
391  }
392  options[name] = new option_without_value(name, short_name, desc);
393  ordered.push_back(options[name]);
394  }
395 
396  template<class T>
397  void add(const std::string &name,
398  char short_name = 0,
399  const std::string &desc = "",
400  bool need = true,
401  const T def = T()) {
402  add(name, short_name, desc, need, def, default_reader<T>());
403  }
404 
405  template<class T, class F>
406  void add(const std::string &name,
407  char short_name = 0,
408  const std::string &desc = "",
409  bool need = true,
410  const T def = T(),
411  F reader = F()) {
412  if (options.count(name)) {
413  throw_cmdline_error("multiple definition: " + name);
414  }
415  options[name] = new option_with_value_with_reader<T, F>(name, short_name, need, def, desc, reader);
416  ordered.push_back(options[name]);
417  }
418 
419  void footer(const std::string &f) {
420  ftr = f;
421  }
422 
423  void set_program_name(const std::string &name) {
424  prog_name = name;
425  }
426 
427  bool exist(const std::string &name) const {
428  if (options.count(name) == 0) {
429  throw_cmdline_error("there is no flag: --" + name);
430  }
431  return options.find(name)->second->has_set();
432  }
433 
434  template<class T>
435  const T &get(const std::string &name) const {
436  if (options.count(name) == 0) {
437  throw_cmdline_error("there is no flag: --" + name);
438  }
439 #ifndef HALIDE_ENABLE_RTTI
440  const option_with_value<T> *p = reinterpret_cast<const option_with_value<T> *>(options.find(name)->second);
441  return p->get();
442 #else
443  const option_with_value<T> *p = dynamic_cast<const option_with_value<T> *>(options.find(name)->second);
444  if (p == nullptr) {
445  throw_cmdline_error("type mismatch flag '" + name + "'");
446  }
447  return p->get();
448 #endif
449  }
450 
451  const std::vector<std::string> &rest() const {
452  return others;
453  }
454 
455  bool parse(const std::string &arg) {
456  std::vector<std::string> args;
457 
458  std::string buf;
459  bool in_quote = false;
460  for (std::string::size_type i = 0; i < arg.length(); i++) {
461  if (arg[i] == '\"') {
462  in_quote = !in_quote;
463  continue;
464  }
465 
466  if (arg[i] == ' ' && !in_quote) {
467  args.push_back(buf);
468  buf = "";
469  continue;
470  }
471 
472  if (arg[i] == '\\') {
473  i++;
474  if (i >= arg.length()) {
475  errors.emplace_back("unexpected occurrence of '\\' at end of string");
476  return false;
477  }
478  }
479 
480  buf += arg[i];
481  }
482 
483  if (in_quote) {
484  errors.emplace_back("quote is not closed");
485  return false;
486  }
487 
488  if (buf.length() > 0) {
489  args.push_back(buf);
490  }
491 
492  for (size_t i = 0; i < args.size(); i++) {
493  std::cout << "\"" << args[i] << "\"" << std::endl;
494  }
495 
496  return parse(args);
497  }
498 
499  bool parse(const std::vector<std::string> &args) {
500  int argc = static_cast<int>(args.size());
501  std::vector<const char *> argv(argc);
502 
503  for (int i = 0; i < argc; i++) {
504  argv[i] = args[i].c_str();
505  }
506 
507  return parse(argc, &argv[0]);
508  }
509 
510  bool parse(int argc, const char *const argv[]) {
511  errors.clear();
512  others.clear();
513 
514  if (argc < 1) {
515  errors.emplace_back("argument number must be longer than 0");
516  return false;
517  }
518  if (prog_name.empty()) {
519  prog_name = argv[0];
520  }
521 
522  std::map<char, std::string> lookup;
523  for (std::map<std::string, option_base *>::iterator p = options.begin();
524  p != options.end(); p++) {
525  if (p->first.length() == 0) {
526  continue;
527  }
528  char initial = p->second->short_name();
529  if (initial) {
530  if (lookup.count(initial) > 0) {
531  lookup[initial] = "";
532  errors.push_back(std::string("short option '") + initial + "' is ambiguous");
533  return false;
534  } else {
535  lookup[initial] = p->first;
536  }
537  }
538  }
539 
540  for (int i = 1; i < argc; i++) {
541  if (strncmp(argv[i], "--", 2) == 0) {
542  const char *p = strchr(argv[i] + 2, '=');
543  if (p) {
544  std::string name(argv[i] + 2, p);
545  std::string val(p + 1);
546  set_option(name, val);
547  } else {
548  std::string name(argv[i] + 2);
549  if (options.count(name) == 0) {
550  errors.push_back("undefined option: --" + name);
551  continue;
552  }
553  if (options[name]->has_value()) {
554  if (i + 1 >= argc) {
555  errors.push_back("option needs value: --" + name);
556  continue;
557  } else {
558  i++;
559  set_option(name, argv[i]);
560  }
561  } else {
562  set_option(name);
563  }
564  }
565  } else if (strncmp(argv[i], "-", 1) == 0) {
566  if (!argv[i][1]) {
567  continue;
568  }
569  char last = argv[i][1];
570  for (int j = 2; argv[i][j]; j++) {
571  last = argv[i][j];
572  if (lookup.count(argv[i][j - 1]) == 0) {
573  errors.push_back(std::string("undefined short option: -") + argv[i][j - 1]);
574  continue;
575  }
576  if (lookup[argv[i][j - 1]].empty()) {
577  errors.push_back(std::string("ambiguous short option: -") + argv[i][j - 1]);
578  continue;
579  }
580  set_option(lookup[argv[i][j - 1]]);
581  }
582 
583  if (lookup.count(last) == 0) {
584  errors.push_back(std::string("undefined short option: -") + last);
585  continue;
586  }
587  if (lookup[last].empty()) {
588  errors.push_back(std::string("ambiguous short option: -") + last);
589  continue;
590  }
591 
592  if (i + 1 < argc && options[lookup[last]]->has_value()) {
593  set_option(lookup[last], argv[i + 1]);
594  i++;
595  } else {
596  set_option(lookup[last]);
597  }
598  } else {
599  others.emplace_back(argv[i]);
600  }
601  }
602 
603  for (std::map<std::string, option_base *>::iterator p = options.begin();
604  p != options.end(); p++) {
605  if (!p->second->valid()) {
606  errors.push_back("need option: --" + std::string(p->first));
607  }
608  }
609 
610  return errors.empty();
611  }
612 
613  void parse_check(const std::string &arg) {
614  if (!options.count("help")) {
615  add("help", '?', "print this message");
616  }
617  check(0, parse(arg));
618  }
619 
620  void parse_check(const std::vector<std::string> &args) {
621  if (!options.count("help")) {
622  add("help", '?', "print this message");
623  }
624  check(args.size(), parse(args));
625  }
626 
627  void parse_check(int argc, char *argv[]) {
628  if (!options.count("help")) {
629  add("help", '?', "print this message");
630  }
631  check(argc, parse(argc, argv));
632  }
633 
634  std::string error() const {
635  return !errors.empty() ? errors[0] : "";
636  }
637 
638  std::string error_full() const {
639  std::ostringstream oss;
640  for (size_t i = 0; i < errors.size(); i++) {
641  oss << errors[i] << std::endl;
642  }
643  return oss.str();
644  }
645 
646  std::string usage() const {
647  std::ostringstream oss;
648  oss << "usage: " << prog_name << " ";
649  for (size_t i = 0; i < ordered.size(); i++) {
650  if (ordered[i]->must()) {
651  oss << ordered[i]->short_description() << " ";
652  }
653  }
654 
655  oss << "[options] ... " << ftr << std::endl;
656  oss << "options:" << std::endl;
657 
658  size_t max_width = 0;
659  for (size_t i = 0; i < ordered.size(); i++) {
660  max_width = std::max(max_width, ordered[i]->name().length());
661  }
662  for (size_t i = 0; i < ordered.size(); i++) {
663  if (ordered[i]->short_name()) {
664  oss << " -" << ordered[i]->short_name() << ", ";
665  } else {
666  oss << " ";
667  }
668 
669  oss << "--" << ordered[i]->name();
670  for (size_t j = ordered[i]->name().length(); j < max_width + 4; j++) {
671  oss << ' ';
672  }
673  oss << ordered[i]->description() << std::endl;
674  }
675  return oss.str();
676  }
677 
678 private:
679  void check(int argc, bool ok) {
680  if ((argc == 1 && !ok) || exist("help")) {
681  std::cerr << usage();
682  exit(0);
683  }
684 
685  if (!ok) {
686  std::cerr << error() << std::endl
687  << usage();
688  exit(1);
689  }
690  }
691 
692  void set_option(const std::string &name) {
693  if (options.count(name) == 0) {
694  errors.push_back("undefined option: --" + name);
695  return;
696  }
697  if (!options[name]->set()) {
698  errors.push_back("option needs value: --" + name);
699  return;
700  }
701  }
702 
703  void set_option(const std::string &name, const std::string &value) {
704  if (options.count(name) == 0) {
705  errors.push_back("undefined option: --" + name);
706  return;
707  }
708  if (!options[name]->set(value)) {
709  errors.push_back("option value is invalid: --" + name + "=" + value);
710  return;
711  }
712  }
713 
714  class option_base {
715  public:
716  virtual ~option_base() = default;
717 
718  virtual bool has_value() const = 0;
719  virtual bool set() = 0;
720  virtual bool set(const std::string &value) = 0;
721  virtual bool has_set() const = 0;
722  virtual bool valid() const = 0;
723  virtual bool must() const = 0;
724 
725  virtual const std::string &name() const = 0;
726  virtual char short_name() const = 0;
727  virtual const std::string &description() const = 0;
728  virtual std::string short_description() const = 0;
729  };
730 
731  class option_without_value : public option_base {
732  public:
733  option_without_value(const std::string &name,
734  char short_name,
735  const std::string &desc)
736  : nam(name), snam(short_name), desc(desc), has(false) {
737  }
738  ~option_without_value() override = default;
739 
740  bool has_value() const override {
741  return false;
742  }
743 
744  bool set() override {
745  has = true;
746  return true;
747  }
748 
749  bool set(const std::string &) override {
750  return false;
751  }
752 
753  bool has_set() const override {
754  return has;
755  }
756 
757  bool valid() const override {
758  return true;
759  }
760 
761  bool must() const override {
762  return false;
763  }
764 
765  const std::string &name() const override {
766  return nam;
767  }
768 
769  char short_name() const override {
770  return snam;
771  }
772 
773  const std::string &description() const override {
774  return desc;
775  }
776 
777  std::string short_description() const override {
778  return "--" + nam;
779  }
780 
781  private:
782  std::string nam;
783  char snam;
784  std::string desc;
785  bool has;
786  };
787 
788  template<class T>
789  class option_with_value : public option_base {
790  public:
791  option_with_value(const std::string &name,
792  char short_name,
793  bool need,
794  const T &def,
795  const std::string &desc)
796  : nam(name), snam(short_name), need(need), has(false), def(def), actual(def) {
797  this->desc = full_description(desc);
798  }
799  ~option_with_value() override = default;
800 
801  const T &get() const {
802  return actual;
803  }
804 
805  bool has_value() const override {
806  return true;
807  }
808 
809  bool set() override {
810  return false;
811  }
812 
813  bool set(const std::string &value) override {
814 #ifdef HALIDE_WITH_EXCEPTIONS
815  try {
816  actual = read(value);
817  has = true;
818  } catch (const std::exception &e) {
819  std::cout << "Exception was caught: " << e.what() << std::endl;
820  return false;
821  }
822  return true;
823 #else
824  actual = read(value);
825  has = true;
826  return true;
827 #endif
828  }
829 
830  bool has_set() const override {
831  return has;
832  }
833 
834  bool valid() const override {
835  if (need && !has) {
836  return false;
837  }
838  return true;
839  }
840 
841  bool must() const override {
842  return need;
843  }
844 
845  const std::string &name() const override {
846  return nam;
847  }
848 
849  char short_name() const override {
850  return snam;
851  }
852 
853  const std::string &description() const override {
854  return desc;
855  }
856 
857  std::string short_description() const override {
858  return "--" + nam + "=" + detail::readable_typename<T>();
859  }
860 
861  protected:
862  std::string full_description(const std::string &desc) {
863  return desc + " (" + detail::readable_typename<T>() +
864  (need ? "" : " [=" + detail::default_value<T>(def) + "]") + ")";
865  }
866 
867  virtual T read(const std::string &s) = 0;
868 
869  std::string nam;
870  char snam;
871  bool need;
872  std::string desc;
873 
874  bool has;
875  T def;
876  T actual;
877  };
878 
879  template<class T, class F>
880  class option_with_value_with_reader : public option_with_value<T> {
881  public:
882  option_with_value_with_reader(const std::string &name,
883  char short_name,
884  bool need,
885  const T def,
886  const std::string &desc,
887  F reader)
888  : option_with_value<T>(name, short_name, need, def, desc), reader(reader) {
889  }
890 
891  private:
892  T read(const std::string &s) override {
893  return reader(s);
894  }
895 
896  F reader;
897  };
898 
899  std::map<std::string, option_base *> options;
900  std::vector<option_base *> ordered;
901  std::string ftr;
902 
903  std::string prog_name;
904  std::vector<std::string> others;
905 
906  std::vector<std::string> errors;
907 };
908 
909 } // namespace cmdline
static Target cast(const Source &arg)
Definition: cmdline.h:90
static Target cast(const std::string &arg)
Definition: cmdline.h:108
static std::string cast(const Source &arg)
Definition: cmdline.h:98
static Target cast(const Source &arg)
Definition: cmdline.h:76
void footer(const std::string &f)
Definition: cmdline.h:419
std::string error_full() const
Definition: cmdline.h:638
void parse_check(const std::vector< std::string > &args)
Definition: cmdline.h:620
void add(const std::string &name, char short_name=0, const std::string &desc="")
Definition: cmdline.h:386
std::string usage() const
Definition: cmdline.h:646
const std::vector< std::string > & rest() const
Definition: cmdline.h:451
parser()=default
bool parse(const std::vector< std::string > &args)
Definition: cmdline.h:499
const T & get(const std::string &name) const
Definition: cmdline.h:435
bool parse(int argc, const char *const argv[])
Definition: cmdline.h:510
std::string error() const
Definition: cmdline.h:634
void parse_check(int argc, char *argv[])
Definition: cmdline.h:627
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:406
bool parse(const std::string &arg)
Definition: cmdline.h:455
bool exist(const std::string &name) const
Definition: cmdline.h:427
void parse_check(const std::string &arg)
Definition: cmdline.h:613
void add(const std::string &name, char short_name=0, const std::string &desc="", bool need=true, const T def=T())
Definition: cmdline.h:397
void set_program_name(const std::string &name)
Definition: cmdline.h:423
unsigned long DWORD
Definition: mini_d3d12.h:182
HALIDE_ALWAYS_INLINE auto cast(halide_type_t t, A &&a) noexcept -> CastOp< decltype(pattern_arg(a))>
Definition: IRMatch.h:2032
Expr max(const FuncRef &a, const FuncRef &b)
Definition: Func.h:581
std::string default_value(T def)
Definition: cmdline.h:164
std::string readable_typename< int >()
Definition: cmdline.h:180
Target lexical_cast(const Source &arg)
Definition: cmdline.h:129
std::string readable_typename()
Definition: cmdline.h:155
void throw_bad_cast()
Definition: cmdline.h:67
std::string readable_typename< bool >()
Definition: cmdline.h:175
range_reader< T > range(const T &low, const T &high)
Definition: cmdline.h:238
void throw_cmdline_error(const std::string &s)
Definition: cmdline.h:207
oneof_reader< T > oneof(T a1)
Definition: cmdline.h:260
char * buf
Definition: printer.h:32
const char * strchr(const char *s, int c)
int strncmp(const char *s, const char *t, size_t n)
void free(void *)
T operator()(const std::string &str)
Definition: cmdline.h:215
static const bool value
Definition: cmdline.h:120
T operator()(const std::string &s)
Definition: cmdline.h:244
void add(const T &v)
Definition: cmdline.h:251
range_reader(const T &low, const T &high)
Definition: cmdline.h:222
T operator()(const std::string &s) const
Definition: cmdline.h:225