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  return ret;
83  }
84 };
85 
86 template<typename Target, typename Source>
87 class lexical_cast_t<Target, Source, true> {
88 public:
89  static Target cast(const Source &arg) {
90  return arg;
91  }
92 };
93 
94 template<typename Source>
95 class lexical_cast_t<std::string, Source, false> {
96 public:
97  static std::string cast(const Source &arg) {
98  std::ostringstream ss;
99  ss << arg;
100  return ss.str();
101  }
102 };
103 
104 template<typename Target>
105 class lexical_cast_t<Target, std::string, false> {
106 public:
107  static Target cast(const std::string &arg) {
108  Target ret;
109  std::istringstream ss(arg);
110  if (!(ss >> ret && ss.eof()))
111  throw_bad_cast();
112  return ret;
113  }
114 };
115 
116 template<typename T1, typename T2>
117 struct is_same {
118  static const bool value = false;
119 };
120 
121 template<typename T>
122 struct is_same<T, T> {
123  static const bool value = true;
124 };
125 
126 template<typename Target, typename Source>
127 Target lexical_cast(const Source &arg) {
129 }
130 
131 static inline std::string demangle(const std::string &name) {
132 #if !defined(_WIN32)
133  int status = 0;
134  char *p = abi::__cxa_demangle(name.c_str(), 0, 0, &status);
135  std::string ret(p);
136  free(p);
137  return ret;
138 #else
139  char demangled_name[8192];
140  if (UnDecorateSymbolName(name.c_str(), demangled_name, sizeof(demangled_name),
141  UNDNAME_COMPLETE)) {
142  std::string ret(demangled_name);
143  return ret;
144  } else {
145  DWORD error = GetLastError();
146  std::cout << "UnDecorateSymbolName error: " << error << std::endl;
147  return name;
148  }
149 #endif
150 }
151 
152 template<class T>
153 std::string readable_typename() {
154 #ifndef HALIDE_ENABLE_RTTI
155  return "unrecognized type";
156 #else
157  return demangle(typeid(T).name());
158 #endif
159 }
160 
161 template<class T>
162 std::string default_value(T def) {
163  return detail::lexical_cast<std::string>(def);
164 }
165 
166 template<>
167 inline std::string readable_typename<std::string>() {
168  return "string";
169 }
170 
171 #ifndef HALIDE_ENABLE_RTTI
172 template<>
173 inline std::string readable_typename<bool>() {
174  return "bool";
175 }
176 
177 template<>
178 inline std::string readable_typename<int>() {
179  return "int";
180 }
181 #endif
182 
183 } // namespace detail
184 
185 //-----
186 
187 #ifdef HALIDE_WITH_EXCEPTIONS
188 class cmdline_error : public std::exception {
189 public:
190  cmdline_error(const std::string &msg)
191  : msg(msg) {
192  }
193  ~cmdline_error() throw() {
194  }
195  const char *what() const throw() override {
196  return msg.c_str();
197  }
198 
199 private:
200  std::string msg;
201 };
202 inline void throw_cmdline_error(const std::string &s) {
203  throw cmdline::cmdline_error(s);
204 }
205 #else
206 inline void throw_cmdline_error(const std::string &s) {
207  std::cerr << "error: " << s << "\n";
208  exit(1);
209 }
210 #endif
211 
212 template<class T>
214  T operator()(const std::string &str) {
215  return detail::lexical_cast<T>(str);
216  }
217 };
218 
219 template<class T>
220 struct range_reader {
221  range_reader(const T &low, const T &high)
222  : low(low), high(high) {
223  }
224  T operator()(const std::string &s) const {
225  T ret = default_reader<T>()(s);
226  if (!(ret >= low && ret <= high)) throw_cmdline_error("range_error");
227  return ret;
228  }
229 
230 private:
231  T low, high;
232 };
233 
234 template<class T>
235 range_reader<T> range(const T &low, const T &high) {
236  return range_reader<T>(low, high);
237 }
238 
239 template<class T>
240 struct oneof_reader {
241  T operator()(const std::string &s) {
242  T ret = default_reader<T>()(s);
243  if (std::find(alt.begin(), alt.end(), ret) == alt.end())
245  return ret;
246  }
247  void add(const T &v) {
248  alt.push_back(v);
249  }
250 
251 private:
252  std::vector<T> alt;
253 };
254 
255 template<class T>
257  oneof_reader<T> ret;
258  ret.add(a1);
259  return ret;
260 }
261 
262 template<class T>
263 oneof_reader<T> oneof(T a1, T a2) {
264  oneof_reader<T> ret;
265  ret.add(a1);
266  ret.add(a2);
267  return ret;
268 }
269 
270 template<class T>
271 oneof_reader<T> oneof(T a1, T a2, T a3) {
272  oneof_reader<T> ret;
273  ret.add(a1);
274  ret.add(a2);
275  ret.add(a3);
276  return ret;
277 }
278 
279 template<class T>
280 oneof_reader<T> oneof(T a1, T a2, T a3, T a4) {
281  oneof_reader<T> ret;
282  ret.add(a1);
283  ret.add(a2);
284  ret.add(a3);
285  ret.add(a4);
286  return ret;
287 }
288 
289 template<class T>
290 oneof_reader<T> oneof(T a1, T a2, T a3, T a4, T a5) {
291  oneof_reader<T> ret;
292  ret.add(a1);
293  ret.add(a2);
294  ret.add(a3);
295  ret.add(a4);
296  ret.add(a5);
297  return ret;
298 }
299 
300 template<class T>
301 oneof_reader<T> oneof(T a1, T a2, T a3, T a4, T a5, T a6) {
302  oneof_reader<T> ret;
303  ret.add(a1);
304  ret.add(a2);
305  ret.add(a3);
306  ret.add(a4);
307  ret.add(a5);
308  ret.add(a6);
309  return ret;
310 }
311 
312 template<class T>
313 oneof_reader<T> oneof(T a1, T a2, T a3, T a4, T a5, T a6, T a7) {
314  oneof_reader<T> ret;
315  ret.add(a1);
316  ret.add(a2);
317  ret.add(a3);
318  ret.add(a4);
319  ret.add(a5);
320  ret.add(a6);
321  ret.add(a7);
322  return ret;
323 }
324 
325 template<class T>
326 oneof_reader<T> oneof(T a1, T a2, T a3, T a4, T a5, T a6, T a7, T a8) {
327  oneof_reader<T> ret;
328  ret.add(a1);
329  ret.add(a2);
330  ret.add(a3);
331  ret.add(a4);
332  ret.add(a5);
333  ret.add(a6);
334  ret.add(a7);
335  ret.add(a8);
336  return ret;
337 }
338 
339 template<class T>
340 oneof_reader<T> oneof(T a1, T a2, T a3, T a4, T a5, T a6, T a7, T a8, T a9) {
341  oneof_reader<T> ret;
342  ret.add(a1);
343  ret.add(a2);
344  ret.add(a3);
345  ret.add(a4);
346  ret.add(a5);
347  ret.add(a6);
348  ret.add(a7);
349  ret.add(a8);
350  ret.add(a9);
351  return ret;
352 }
353 
354 template<class T>
355 oneof_reader<T> oneof(T a1, T a2, T a3, T a4, T a5, T a6, T a7, T a8, T a9, T a10) {
356  oneof_reader<T> ret;
357  ret.add(a1);
358  ret.add(a2);
359  ret.add(a3);
360  ret.add(a4);
361  ret.add(a5);
362  ret.add(a6);
363  ret.add(a7);
364  ret.add(a8);
365  ret.add(a9);
366  ret.add(a10);
367  return ret;
368 }
369 
370 //-----
371 
372 class parser {
373 public:
374  parser() {
375  }
377  for (std::map<std::string, option_base *>::iterator p = options.begin();
378  p != options.end(); p++)
379  delete p->second;
380  }
381 
382  void add(const std::string &name,
383  char short_name = 0,
384  const std::string &desc = "") {
385  if (options.count(name)) throw_cmdline_error("multiple definition: " + name);
386  options[name] = new option_without_value(name, short_name, desc);
387  ordered.push_back(options[name]);
388  }
389 
390  template<class T>
391  void add(const std::string &name,
392  char short_name = 0,
393  const std::string &desc = "",
394  bool need = true,
395  const T def = T()) {
396  add(name, short_name, desc, need, def, default_reader<T>());
397  }
398 
399  template<class T, class F>
400  void add(const std::string &name,
401  char short_name = 0,
402  const std::string &desc = "",
403  bool need = true,
404  const T def = T(),
405  F reader = F()) {
406  if (options.count(name)) throw_cmdline_error("multiple definition: " + name);
407  options[name] = new option_with_value_with_reader<T, F>(name, short_name, need, def, desc, reader);
408  ordered.push_back(options[name]);
409  }
410 
411  void footer(const std::string &f) {
412  ftr = f;
413  }
414 
415  void set_program_name(const std::string &name) {
416  prog_name = name;
417  }
418 
419  bool exist(const std::string &name) const {
420  if (options.count(name) == 0) throw_cmdline_error("there is no flag: --" + name);
421  return options.find(name)->second->has_set();
422  }
423 
424  template<class T>
425  const T &get(const std::string &name) const {
426  if (options.count(name) == 0) throw_cmdline_error("there is no flag: --" + name);
427 #ifndef HALIDE_ENABLE_RTTI
428  const option_with_value<T> *p = reinterpret_cast<const option_with_value<T> *>(options.find(name)->second);
429  return p->get();
430 #else
431  const option_with_value<T> *p = dynamic_cast<const option_with_value<T> *>(options.find(name)->second);
432  if (p == NULL) throw_cmdline_error("type mismatch flag '" + name + "'");
433  return p->get();
434 #endif
435  }
436 
437  const std::vector<std::string> &rest() const {
438  return others;
439  }
440 
441  bool parse(const std::string &arg) {
442  std::vector<std::string> args;
443 
444  std::string buf;
445  bool in_quote = false;
446  for (std::string::size_type i = 0; i < arg.length(); i++) {
447  if (arg[i] == '\"') {
448  in_quote = !in_quote;
449  continue;
450  }
451 
452  if (arg[i] == ' ' && !in_quote) {
453  args.push_back(buf);
454  buf = "";
455  continue;
456  }
457 
458  if (arg[i] == '\\') {
459  i++;
460  if (i >= arg.length()) {
461  errors.push_back("unexpected occurrence of '\\' at end of string");
462  return false;
463  }
464  }
465 
466  buf += arg[i];
467  }
468 
469  if (in_quote) {
470  errors.push_back("quote is not closed");
471  return false;
472  }
473 
474  if (buf.length() > 0)
475  args.push_back(buf);
476 
477  for (size_t i = 0; i < args.size(); i++)
478  std::cout << "\"" << args[i] << "\"" << std::endl;
479 
480  return parse(args);
481  }
482 
483  bool parse(const std::vector<std::string> &args) {
484  int argc = static_cast<int>(args.size());
485  std::vector<const char *> argv(argc);
486 
487  for (int i = 0; i < argc; i++)
488  argv[i] = args[i].c_str();
489 
490  return parse(argc, &argv[0]);
491  }
492 
493  bool parse(int argc, const char *const argv[]) {
494  errors.clear();
495  others.clear();
496 
497  if (argc < 1) {
498  errors.push_back("argument number must be longer than 0");
499  return false;
500  }
501  if (prog_name == "")
502  prog_name = argv[0];
503 
504  std::map<char, std::string> lookup;
505  for (std::map<std::string, option_base *>::iterator p = options.begin();
506  p != options.end(); p++) {
507  if (p->first.length() == 0) continue;
508  char initial = p->second->short_name();
509  if (initial) {
510  if (lookup.count(initial) > 0) {
511  lookup[initial] = "";
512  errors.push_back(std::string("short option '") + initial + "' is ambiguous");
513  return false;
514  } else
515  lookup[initial] = p->first;
516  }
517  }
518 
519  for (int i = 1; i < argc; i++) {
520  if (strncmp(argv[i], "--", 2) == 0) {
521  const char *p = strchr(argv[i] + 2, '=');
522  if (p) {
523  std::string name(argv[i] + 2, p);
524  std::string val(p + 1);
525  set_option(name, val);
526  } else {
527  std::string name(argv[i] + 2);
528  if (options.count(name) == 0) {
529  errors.push_back("undefined option: --" + name);
530  continue;
531  }
532  if (options[name]->has_value()) {
533  if (i + 1 >= argc) {
534  errors.push_back("option needs value: --" + name);
535  continue;
536  } else {
537  i++;
538  set_option(name, argv[i]);
539  }
540  } else {
541  set_option(name);
542  }
543  }
544  } else if (strncmp(argv[i], "-", 1) == 0) {
545  if (!argv[i][1]) continue;
546  char last = argv[i][1];
547  for (int j = 2; argv[i][j]; j++) {
548  last = argv[i][j];
549  if (lookup.count(argv[i][j - 1]) == 0) {
550  errors.push_back(std::string("undefined short option: -") + argv[i][j - 1]);
551  continue;
552  }
553  if (lookup[argv[i][j - 1]] == "") {
554  errors.push_back(std::string("ambiguous short option: -") + argv[i][j - 1]);
555  continue;
556  }
557  set_option(lookup[argv[i][j - 1]]);
558  }
559 
560  if (lookup.count(last) == 0) {
561  errors.push_back(std::string("undefined short option: -") + last);
562  continue;
563  }
564  if (lookup[last] == "") {
565  errors.push_back(std::string("ambiguous short option: -") + last);
566  continue;
567  }
568 
569  if (i + 1 < argc && options[lookup[last]]->has_value()) {
570  set_option(lookup[last], argv[i + 1]);
571  i++;
572  } else {
573  set_option(lookup[last]);
574  }
575  } else {
576  others.push_back(argv[i]);
577  }
578  }
579 
580  for (std::map<std::string, option_base *>::iterator p = options.begin();
581  p != options.end(); p++)
582  if (!p->second->valid())
583  errors.push_back("need option: --" + std::string(p->first));
584 
585  return errors.size() == 0;
586  }
587 
588  void parse_check(const std::string &arg) {
589  if (!options.count("help"))
590  add("help", '?', "print this message");
591  check(0, parse(arg));
592  }
593 
594  void parse_check(const std::vector<std::string> &args) {
595  if (!options.count("help"))
596  add("help", '?', "print this message");
597  check(args.size(), parse(args));
598  }
599 
600  void parse_check(int argc, char *argv[]) {
601  if (!options.count("help"))
602  add("help", '?', "print this message");
603  check(argc, parse(argc, argv));
604  }
605 
606  std::string error() const {
607  return errors.size() > 0 ? errors[0] : "";
608  }
609 
610  std::string error_full() const {
611  std::ostringstream oss;
612  for (size_t i = 0; i < errors.size(); i++)
613  oss << errors[i] << std::endl;
614  return oss.str();
615  }
616 
617  std::string usage() const {
618  std::ostringstream oss;
619  oss << "usage: " << prog_name << " ";
620  for (size_t i = 0; i < ordered.size(); i++) {
621  if (ordered[i]->must())
622  oss << ordered[i]->short_description() << " ";
623  }
624 
625  oss << "[options] ... " << ftr << std::endl;
626  oss << "options:" << std::endl;
627 
628  size_t max_width = 0;
629  for (size_t i = 0; i < ordered.size(); i++) {
630  max_width = std::max(max_width, ordered[i]->name().length());
631  }
632  for (size_t i = 0; i < ordered.size(); i++) {
633  if (ordered[i]->short_name()) {
634  oss << " -" << ordered[i]->short_name() << ", ";
635  } else {
636  oss << " ";
637  }
638 
639  oss << "--" << ordered[i]->name();
640  for (size_t j = ordered[i]->name().length(); j < max_width + 4; j++)
641  oss << ' ';
642  oss << ordered[i]->description() << std::endl;
643  }
644  return oss.str();
645  }
646 
647 private:
648  void check(int argc, bool ok) {
649  if ((argc == 1 && !ok) || exist("help")) {
650  std::cerr << usage();
651  exit(0);
652  }
653 
654  if (!ok) {
655  std::cerr << error() << std::endl
656  << usage();
657  exit(1);
658  }
659  }
660 
661  void set_option(const std::string &name) {
662  if (options.count(name) == 0) {
663  errors.push_back("undefined option: --" + name);
664  return;
665  }
666  if (!options[name]->set()) {
667  errors.push_back("option needs value: --" + name);
668  return;
669  }
670  }
671 
672  void set_option(const std::string &name, const std::string &value) {
673  if (options.count(name) == 0) {
674  errors.push_back("undefined option: --" + name);
675  return;
676  }
677  if (!options[name]->set(value)) {
678  errors.push_back("option value is invalid: --" + name + "=" + value);
679  return;
680  }
681  }
682 
683  class option_base {
684  public:
685  virtual ~option_base() {
686  }
687 
688  virtual bool has_value() const = 0;
689  virtual bool set() = 0;
690  virtual bool set(const std::string &value) = 0;
691  virtual bool has_set() const = 0;
692  virtual bool valid() const = 0;
693  virtual bool must() const = 0;
694 
695  virtual const std::string &name() const = 0;
696  virtual char short_name() const = 0;
697  virtual const std::string &description() const = 0;
698  virtual std::string short_description() const = 0;
699  };
700 
701  class option_without_value : public option_base {
702  public:
703  option_without_value(const std::string &name,
704  char short_name,
705  const std::string &desc)
706  : nam(name), snam(short_name), desc(desc), has(false) {
707  }
708  ~option_without_value() {
709  }
710 
711  bool has_value() const override {
712  return false;
713  }
714 
715  bool set() override {
716  has = true;
717  return true;
718  }
719 
720  bool set(const std::string &) override {
721  return false;
722  }
723 
724  bool has_set() const override {
725  return has;
726  }
727 
728  bool valid() const override {
729  return true;
730  }
731 
732  bool must() const override {
733  return false;
734  }
735 
736  const std::string &name() const override {
737  return nam;
738  }
739 
740  char short_name() const override {
741  return snam;
742  }
743 
744  const std::string &description() const override {
745  return desc;
746  }
747 
748  std::string short_description() const override {
749  return "--" + nam;
750  }
751 
752  private:
753  std::string nam;
754  char snam;
755  std::string desc;
756  bool has;
757  };
758 
759  template<class T>
760  class option_with_value : public option_base {
761  public:
762  option_with_value(const std::string &name,
763  char short_name,
764  bool need,
765  const T &def,
766  const std::string &desc)
767  : nam(name), snam(short_name), need(need), has(false), def(def), actual(def) {
768  this->desc = full_description(desc);
769  }
770  ~option_with_value() {
771  }
772 
773  const T &get() const {
774  return actual;
775  }
776 
777  bool has_value() const override {
778  return true;
779  }
780 
781  bool set() override {
782  return false;
783  }
784 
785  bool set(const std::string &value) override {
786 #ifdef HALIDE_WITH_EXCEPTIONS
787  try {
788  actual = read(value);
789  has = true;
790  } catch (const std::exception &e) {
791  std::cout << "Exception was caught: " << e.what() << std::endl;
792  return false;
793  }
794  return true;
795 #else
796  actual = read(value);
797  has = true;
798  return true;
799 #endif
800  }
801 
802  bool has_set() const override {
803  return has;
804  }
805 
806  bool valid() const override {
807  if (need && !has) return false;
808  return true;
809  }
810 
811  bool must() const override {
812  return need;
813  }
814 
815  const std::string &name() const override {
816  return nam;
817  }
818 
819  char short_name() const override {
820  return snam;
821  }
822 
823  const std::string &description() const override {
824  return desc;
825  }
826 
827  std::string short_description() const override {
828  return "--" + nam + "=" + detail::readable_typename<T>();
829  }
830 
831  protected:
832  std::string full_description(const std::string &desc) {
833  return desc + " (" + detail::readable_typename<T>() +
834  (need ? "" : " [=" + detail::default_value<T>(def) + "]") + ")";
835  }
836 
837  virtual T read(const std::string &s) = 0;
838 
839  std::string nam;
840  char snam;
841  bool need;
842  std::string desc;
843 
844  bool has;
845  T def;
846  T actual;
847  };
848 
849  template<class T, class F>
850  class option_with_value_with_reader : public option_with_value<T> {
851  public:
852  option_with_value_with_reader(const std::string &name,
853  char short_name,
854  bool need,
855  const T def,
856  const std::string &desc,
857  F reader)
858  : option_with_value<T>(name, short_name, need, def, desc), reader(reader) {
859  }
860 
861  private:
862  T read(const std::string &s) override {
863  return reader(s);
864  }
865 
866  F reader;
867  };
868 
869  std::map<std::string, option_base *> options;
870  std::vector<option_base *> ordered;
871  std::string ftr;
872 
873  std::string prog_name;
874  std::vector<std::string> others;
875 
876  std::vector<std::string> errors;
877 };
878 
879 } // namespace cmdline
cmdline::parser::parse
bool parse(const std::string &arg)
Definition: cmdline.h:441
Halide::Internal::IRMatcher::cast
HALIDE_ALWAYS_INLINE auto cast(halide_type_t t, A a) noexcept -> CastOp< decltype(pattern_arg(a))>
Definition: IRMatch.h:1891
cmdline::detail::is_same::value
static const bool value
Definition: cmdline.h:118
NULL
#define NULL
Definition: runtime_internal.h:32
cmdline::parser::parse_check
void parse_check(int argc, char *argv[])
Definition: cmdline.h:600
cmdline::range
range_reader< T > range(const T &low, const T &high)
Definition: cmdline.h:235
cmdline::default_reader
Definition: cmdline.h:213
cmdline::parser::parse_check
void parse_check(const std::vector< std::string > &args)
Definition: cmdline.h:594
cmdline::detail::lexical_cast
Target lexical_cast(const Source &arg)
Definition: cmdline.h:127
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:241
cmdline::parser::usage
std::string usage() const
Definition: cmdline.h:617
cmdline::parser::get
const T & get(const std::string &name) const
Definition: cmdline.h:425
cmdline::detail::readable_typename
std::string readable_typename()
Definition: cmdline.h:153
cmdline::parser::set_program_name
void set_program_name(const std::string &name)
Definition: cmdline.h:415
cmdline::detail::lexical_cast_t< std::string, Source, false >::cast
static std::string cast(const Source &arg)
Definition: cmdline.h:97
cmdline::parser::parse_check
void parse_check(const std::string &arg)
Definition: cmdline.h:588
cmdline::parser
Definition: cmdline.h:372
cmdline::parser::add
void add(const std::string &name, char short_name=0, const std::string &desc="")
Definition: cmdline.h:382
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:610
cmdline::range_reader::operator()
T operator()(const std::string &s) const
Definition: cmdline.h:224
cmdline::parser::rest
const std::vector< std::string > & rest() const
Definition: cmdline.h:437
cmdline::oneof_reader::add
void add(const T &v)
Definition: cmdline.h:247
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:178
cmdline::parser::parse
bool parse(const std::vector< std::string > &args)
Definition: cmdline.h:483
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:173
cmdline::parser::parse
bool parse(int argc, const char *const argv[])
Definition: cmdline.h:493
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:391
cmdline::throw_cmdline_error
void throw_cmdline_error(const std::string &s)
Definition: cmdline.h:206
cmdline::parser::footer
void footer(const std::string &f)
Definition: cmdline.h:411
cmdline::detail::is_same
Definition: cmdline.h:117
cmdline
Definition: cmdline.h:58
cmdline::detail::default_value
std::string default_value(T def)
Definition: cmdline.h:162
cmdline::range_reader
Definition: cmdline.h:220
cmdline::range_reader::range_reader
range_reader(const T &low, const T &high)
Definition: cmdline.h:221
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:107
cmdline::oneof
oneof_reader< T > oneof(T a1)
Definition: cmdline.h:256
buf
char * buf
Definition: printer.h:32
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:400
cmdline::parser::error
std::string error() const
Definition: cmdline.h:606
cmdline::parser::~parser
~parser()
Definition: cmdline.h:376
cmdline::parser::exist
bool exist(const std::string &name) const
Definition: cmdline.h:419
cmdline::detail::lexical_cast_t< Target, Source, true >::cast
static Target cast(const Source &arg)
Definition: cmdline.h:89
Halide::max
Expr max(const FuncRef &a, const FuncRef &b)
Definition: Func.h:580
cmdline::oneof_reader
Definition: cmdline.h:240
cmdline::parser::parser
parser()
Definition: cmdline.h:374
cmdline::default_reader::operator()
T operator()(const std::string &str)
Definition: cmdline.h:214