Halide
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 (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.length() > 0) {
488  args.push_back(buf);
489  }
490 
491  for (auto &arg : args) {
492  std::cout << "\"" << arg << "\"" << std::endl;
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.length() == 0) {
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 << std::endl;
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 << std::endl;
653  oss << "options:" << std::endl;
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() << std::endl;
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() << std::endl
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), has(false) {
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;
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), has(false), 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() << std::endl;
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;
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::parser::parse
bool parse(const std::string &arg)
Definition: cmdline.h:454
Halide::Internal::IRMatcher::cast
HALIDE_ALWAYS_INLINE auto cast(halide_type_t t, A &&a) noexcept -> CastOp< decltype(pattern_arg(a))>
Definition: IRMatch.h:2078
cmdline::detail::is_same::value
static const bool value
Definition: cmdline.h:120
cmdline::parser::parse_check
void parse_check(int argc, char *argv[])
Definition: cmdline.h:624
cmdline::range
range_reader< T > range(const T &low, const T &high)
Definition: cmdline.h:238
cmdline::default_reader
Definition: cmdline.h:214
cmdline::parser::parse_check
void parse_check(const std::vector< std::string > &args)
Definition: cmdline.h:617
cmdline::detail::lexical_cast
Target lexical_cast(const Source &arg)
Definition: cmdline.h:129
strchr
const char * strchr(const char *s, int c)
cmdline::detail::lexical_cast_t
Definition: cmdline.h:74
cmdline::oneof_reader::operator()
T operator()(const std::string &s)
Definition: cmdline.h:244
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::detail::readable_typename
std::string readable_typename()
Definition: cmdline.h:155
cmdline::parser::set_program_name
void set_program_name(const std::string &name)
Definition: cmdline.h:422
cmdline::detail::lexical_cast_t< std::string, Source, false >::cast
static std::string cast(const Source &arg)
Definition: cmdline.h:98
cmdline::parser::parse_check
void parse_check(const std::string &arg)
Definition: cmdline.h:610
cmdline::parser
Definition: cmdline.h:376
cmdline::parser::add
void add(const std::string &name, char short_name=0, const std::string &desc="")
Definition: cmdline.h:385
cmdline::detail::throw_bad_cast
void throw_bad_cast()
Definition: cmdline.h:67
cmdline::parser::error_full
std::string error_full() const
Definition: cmdline.h:635
cmdline::range_reader::operator()
T operator()(const std::string &s) const
Definition: cmdline.h:225
cmdline::parser::rest
const std::vector< std::string > & rest() const
Definition: cmdline.h:450
cmdline::oneof_reader::add
void add(const T &v)
Definition: cmdline.h:251
cmdline::parser::parser
parser()=default
cmdline::detail::lexical_cast_t::cast
static Target cast(const Source &arg)
Definition: cmdline.h:76
cmdline::detail::readable_typename< int >
std::string readable_typename< int >()
Definition: cmdline.h:180
cmdline::parser::parse
bool parse(const std::vector< std::string > &args)
Definition: cmdline.h:498
strncmp
int strncmp(const char *s, const char *t, size_t n)
cmdline::detail::readable_typename< bool >
std::string readable_typename< bool >()
Definition: cmdline.h:175
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::throw_cmdline_error
void throw_cmdline_error(const std::string &s)
Definition: cmdline.h:207
cmdline::parser::footer
void footer(const std::string &f)
Definition: cmdline.h:418
cmdline::detail::is_same
Definition: cmdline.h:119
cmdline
Definition: cmdline.h:58
cmdline::detail::default_value
std::string default_value(T def)
Definition: cmdline.h:164
cmdline::range_reader
Definition: cmdline.h:221
cmdline::range_reader::range_reader
range_reader(const T &low, const T &high)
Definition: cmdline.h:222
DWORD
unsigned long DWORD
Definition: mini_d3d12.h:182
free
void free(void *)
cmdline::detail::lexical_cast_t< Target, std::string, false >::cast
static Target cast(const std::string &arg)
Definition: cmdline.h:108
cmdline::oneof
oneof_reader< T > oneof(T a1)
Definition: cmdline.h:260
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::error
std::string error() const
Definition: cmdline.h:631
cmdline::parser::~parser
~parser()
Definition: cmdline.h:379
cmdline::parser::exist
bool exist(const std::string &name) const
Definition: cmdline.h:426
cmdline::detail::lexical_cast_t< Target, Source, true >::cast
static Target cast(const Source &arg)
Definition: cmdline.h:90
Halide::max
Expr max(const FuncRef &a, const FuncRef &b)
Definition: Func.h:587
cmdline::oneof_reader
Definition: cmdline.h:243
cmdline::default_reader::operator()
T operator()(const std::string &str)
Definition: cmdline.h:215