cxxopts.hpp
Go to the documentation of this file.
1 /*
2 
3 Copyright (c) 2014, 2015, 2016, 2017 Jarryd Beck
4 
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"), to deal
7 in the Software without restriction, including without limitation the rights
8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 copies of the Software, and to permit persons to whom the Software is
10 furnished to do so, subject to the following conditions:
11 
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
14 
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 THE SOFTWARE.
22 
23 */
24 
25 #ifndef CXXOPTS_HPP_INCLUDED
26 #define CXXOPTS_HPP_INCLUDED
27 
28 #include <cstring>
29 #include <cctype>
30 #include <exception>
31 #include <iostream>
32 #include <map>
33 #include <memory>
34 #include <regex>
35 #include <sstream>
36 #include <string>
37 #include <unordered_map>
38 #include <unordered_set>
39 #include <vector>
40 
41 #ifdef __cpp_lib_optional
42 #include <optional>
43 #define CXXOPTS_HAS_OPTIONAL
44 #endif
45 
46 #define CXXOPTS__VERSION_MAJOR 2
47 #define CXXOPTS__VERSION_MINOR 2
48 #define CXXOPTS__VERSION_PATCH 0
49 
50 namespace cxxopts
51 {
52  static constexpr struct
53  {
54  uint8_t major, minor, patch;
55  } version =
56  {
60  };
61 }
62 
63 //when we ask cxxopts to use Unicode, help strings are processed using ICU,
64 //which results in the correct lengths being computed for strings when they
65 //are formatted for the help output
66 //it is necessary to make sure that <unicode/unistr.h> can be found by the
67 //compiler, and that icu-uc is linked in to the binary.
68 
69 #ifdef CXXOPTS_USE_UNICODE
70 #include <unicode/unistr.h>
71 
72 namespace cxxopts
73 {
74  typedef icu::UnicodeString String;
75 
76  inline
77  String
78  toLocalString(std::string s)
79  {
80  return icu::UnicodeString::fromUTF8(std::move(s));
81  }
82 
83  class UnicodeStringIterator : public
84  std::iterator<std::forward_iterator_tag, int32_t>
85  {
86  public:
87 
88  UnicodeStringIterator(const icu::UnicodeString* string, int32_t pos)
89  : s(string)
90  , i(pos)
91  {
92  }
93 
94  value_type
95  operator*() const
96  {
97  return s->char32At(i);
98  }
99 
100  bool
101  operator==(const UnicodeStringIterator& rhs) const
102  {
103  return s == rhs.s && i == rhs.i;
104  }
105 
106  bool
107  operator!=(const UnicodeStringIterator& rhs) const
108  {
109  return !(*this == rhs);
110  }
111 
112  UnicodeStringIterator&
113  operator++()
114  {
115  ++i;
116  return *this;
117  }
118 
119  UnicodeStringIterator
120  operator+(int32_t v)
121  {
122  return UnicodeStringIterator(s, i + v);
123  }
124 
125  private:
126  const icu::UnicodeString* s;
127  int32_t i;
128  };
129 
130  inline
131  String&
133  {
134  return s.append(std::move(a));
135  }
136 
137  inline
138  String&
139  stringAppend(String& s, int n, UChar32 c)
140  {
141  for (int i = 0; i != n; ++i)
142  {
143  s.append(c);
144  }
145 
146  return s;
147  }
148 
149  template <typename Iterator>
150  String&
151  stringAppend(String& s, Iterator begin, Iterator end)
152  {
153  while (begin != end)
154  {
155  s.append(*begin);
156  ++begin;
157  }
158 
159  return s;
160  }
161 
162  inline
163  size_t
164  stringLength(const String& s)
165  {
166  return s.length();
167  }
168 
169  inline
170  std::string
171  toUTF8String(const String& s)
172  {
173  std::string result;
174  s.toUTF8String(result);
175 
176  return result;
177  }
178 
179  inline
180  bool
181  empty(const String& s)
182  {
183  return s.isEmpty();
184  }
185 }
186 
187 namespace std
188 {
189  inline
190  cxxopts::UnicodeStringIterator
191  begin(const icu::UnicodeString& s)
192  {
193  return cxxopts::UnicodeStringIterator(&s, 0);
194  }
195 
196  inline
197  cxxopts::UnicodeStringIterator
198  end(const icu::UnicodeString& s)
199  {
200  return cxxopts::UnicodeStringIterator(&s, s.length());
201  }
202 }
203 
204 //ifdef CXXOPTS_USE_UNICODE
205 #else
206 
207 namespace cxxopts
208 {
209  typedef std::string String;
210 
211  template <typename T>
212  T
214  {
215  return std::forward<T>(t);
216  }
217 
218  inline
219  size_t
221  {
222  return s.length();
223  }
224 
225  inline
226  String&
228  {
229  return s.append(std::move(a));
230  }
231 
232  inline
233  String&
234  stringAppend(String& s, size_t n, char c)
235  {
236  return s.append(n, c);
237  }
238 
239  template <typename Iterator>
240  String&
241  stringAppend(String& s, Iterator begin, Iterator end)
242  {
243  return s.append(begin, end);
244  }
245 
246  template <typename T>
247  std::string
249  {
250  return std::forward<T>(t);
251  }
252 
253  inline
254  bool
255  empty(const std::string& s)
256  {
257  return s.empty();
258  }
259 }
260 
261 //ifdef CXXOPTS_USE_UNICODE
262 #endif
263 
264 namespace cxxopts
265 {
266  namespace
267  {
268 #ifdef _WIN32
269  const std::string LQUOTE("\'");
270  const std::string RQUOTE("\'");
271 #else
272  const std::string LQUOTE("‘");
273  const std::string RQUOTE("’");
274 #endif
275  }
276 
277  class Value : public std::enable_shared_from_this<Value>
278  {
279  public:
280 
281  virtual ~Value() = default;
282 
283  virtual
284  std::shared_ptr<Value>
285  clone() const = 0;
286 
287  virtual void
288  parse(const std::string& text) const = 0;
289 
290  virtual void
291  parse() const = 0;
292 
293  virtual bool
294  has_default() const = 0;
295 
296  virtual bool
297  is_container() const = 0;
298 
299  virtual bool
300  has_implicit() const = 0;
301 
302  virtual std::string
303  get_default_value() const = 0;
304 
305  virtual std::string
306  get_implicit_value() const = 0;
307 
308  virtual std::shared_ptr<Value>
309  default_value(const std::string& value) = 0;
310 
311  virtual std::shared_ptr<Value>
312  implicit_value(const std::string& value) = 0;
313 
314  virtual bool
315  is_boolean() const = 0;
316  };
317 
318  class OptionException : public std::exception
319  {
320  public:
321  OptionException(const std::string& message)
322  : m_message(message)
323  {
324  }
325 
326  virtual const char*
327  what() const noexcept
328  {
329  return m_message.c_str();
330  }
331 
332  private:
333  std::string m_message;
334  };
335 
337  {
338  public:
339 
340  OptionSpecException(const std::string& message)
342  {
343  }
344  };
345 
347  {
348  public:
349  OptionParseException(const std::string& message)
351  {
352  }
353  };
354 
356  {
357  public:
358  option_exists_error(const std::string& option)
359  : OptionSpecException("Option " + LQUOTE + option + RQUOTE + " already exists")
360  {
361  }
362  };
363 
365  {
366  public:
367  invalid_option_format_error(const std::string& format)
368  : OptionSpecException("Invalid option format " + LQUOTE + format + RQUOTE)
369  {
370  }
371  };
372 
374  {
375  public:
376  option_syntax_exception(const std::string& text)
377  : OptionParseException("Argument " + LQUOTE + text + RQUOTE +
378  " starts with a - but has incorrect syntax")
379  {
380  }
381  };
382 
384  {
385  public:
387  : OptionParseException("Option " + LQUOTE + option + RQUOTE + " does not exist")
388  {
389  }
390  };
391 
393  {
394  public:
395  missing_argument_exception(const std::string& option)
397  "Option " + LQUOTE + option + RQUOTE + " is missing an argument"
398  )
399  {
400  }
401  };
402 
404  {
405  public:
408  "Option " + LQUOTE + option + RQUOTE + " requires an argument"
409  )
410  {
411  }
412  };
413 
415  {
416  public:
418  (
419  const std::string& option,
420  const std::string& arg
421  )
423  "Option " + LQUOTE + option + RQUOTE +
424  " does not take an argument, but argument " +
425  LQUOTE + arg + RQUOTE + " given"
426  )
427  {
428  }
429  };
430 
432  {
433  public:
435  : OptionParseException("Option " + LQUOTE + option + RQUOTE + " not present")
436  {
437  }
438  };
439 
441  {
442  public:
444  (
445  const std::string& arg
446  )
448  "Argument " + LQUOTE + arg + RQUOTE + " failed to parse"
449  )
450  {
451  }
452  };
453 
455  {
456  public:
457  option_required_exception(const std::string& option)
459  "Option " + LQUOTE + option + RQUOTE + " is required but not present"
460  )
461  {
462  }
463  };
464 
465  namespace values
466  {
467  namespace
468  {
469  std::basic_regex<char> integer_pattern
470  ("(-)?(0x)?([0-9a-zA-Z]+)|((0x)?0)");
471  std::basic_regex<char> truthy_pattern
472  ("(t|T)(rue)?");
473  std::basic_regex<char> falsy_pattern
474  ("((f|F)(alse)?)?");
475  }
476 
477  namespace detail
478  {
479  template <typename T, bool B>
480  struct SignedCheck;
481 
482  template <typename T>
483  struct SignedCheck<T, true>
484  {
485  template <typename U>
486  void
487  operator()(bool negative, U u, const std::string& text)
488  {
489  if (negative)
490  {
491  if (u > static_cast<U>(-(std::numeric_limits<T>::min)()))
492  {
493  throw argument_incorrect_type(text);
494  }
495  }
496  else
497  {
498  if (u > static_cast<U>((std::numeric_limits<T>::max)()))
499  {
500  throw argument_incorrect_type(text);
501  }
502  }
503  }
504  };
505 
506  template <typename T>
507  struct SignedCheck<T, false>
508  {
509  template <typename U>
510  void
511  operator()(bool, U, const std::string&) {}
512  };
513 
514  template <typename T, typename U>
515  void
516  check_signed_range(bool negative, U value, const std::string& text)
517  {
519  }
520  }
521 
522  template <typename R, typename T>
523  R
524  checked_negate(T&& t, const std::string&, std::true_type)
525  {
526  // if we got to here, then `t` is a positive number that fits into
527  // `R`. So to avoid MSVC C4146, we first cast it to `R`.
528  // See https://github.com/jarro2783/cxxopts/issues/62 for more details.
529  return -static_cast<R>(t);
530  }
531 
532  template <typename R, typename T>
533  T
534  checked_negate(T&&, const std::string& text, std::false_type)
535  {
536  throw argument_incorrect_type(text);
537  }
538 
539  template <typename T>
540  void
541  integer_parser(const std::string& text, T& value)
542  {
543  std::smatch match;
544  std::regex_match(text, match, integer_pattern);
545 
546  if (match.length() == 0)
547  {
548  throw argument_incorrect_type(text);
549  }
550 
551  if (match.length(4) > 0)
552  {
553  value = 0;
554  return;
555  }
556 
557  using US = typename std::make_unsigned<T>::type;
558 
559  constexpr auto umax = (std::numeric_limits<US>::max)();
560  constexpr bool is_signed = std::numeric_limits<T>::is_signed;
561  const bool negative = match.length(1) > 0;
562  const uint8_t base = match.length(2) > 0 ? 16 : 10;
563 
564  auto value_match = match[3];
565 
566  US result = 0;
567 
568  for (auto iter = value_match.first; iter != value_match.second; ++iter)
569  {
570  US digit = 0;
571 
572  if (*iter >= '0' && *iter <= '9')
573  {
574  digit = *iter - '0';
575  }
576  else if (base == 16 && *iter >= 'a' && *iter <= 'f')
577  {
578  digit = *iter - 'a' + 10;
579  }
580  else if (base == 16 && *iter >= 'A' && *iter <= 'F')
581  {
582  digit = *iter - 'A' + 10;
583  }
584  else
585  {
586  throw argument_incorrect_type(text);
587  }
588 
589  if (umax - digit < result * base)
590  {
591  throw argument_incorrect_type(text);
592  }
593 
594  result = result * base + digit;
595  }
596 
597  detail::check_signed_range<T>(negative, result, text);
598 
599  if (negative)
600  {
601  value = checked_negate<T>(result,
602  text,
603  std::integral_constant<bool, is_signed>());
604  }
605  else
606  {
607  value = result;
608  }
609  }
610 
611  template <typename T>
612  void stringstream_parser(const std::string& text, T& value)
613  {
614  std::stringstream in(text);
615  in >> value;
616  if (!in)
617  {
618  throw argument_incorrect_type(text);
619  }
620  }
621 
622  inline
623  void
624  parse_value(const std::string& text, uint8_t& value)
625  {
626  integer_parser(text, value);
627  }
628 
629  inline
630  void
631  parse_value(const std::string& text, int8_t& value)
632  {
633  integer_parser(text, value);
634  }
635 
636  inline
637  void
638  parse_value(const std::string& text, uint16_t& value)
639  {
640  integer_parser(text, value);
641  }
642 
643  inline
644  void
645  parse_value(const std::string& text, int16_t& value)
646  {
647  integer_parser(text, value);
648  }
649 
650  inline
651  void
652  parse_value(const std::string& text, uint32_t& value)
653  {
654  integer_parser(text, value);
655  }
656 
657  inline
658  void
659  parse_value(const std::string& text, int32_t& value)
660  {
661  integer_parser(text, value);
662  }
663 
664  inline
665  void
666  parse_value(const std::string& text, uint64_t& value)
667  {
668  integer_parser(text, value);
669  }
670 
671  inline
672  void
673  parse_value(const std::string& text, int64_t& value)
674  {
675  integer_parser(text, value);
676  }
677 
678  inline
679  void
680  parse_value(const std::string& text, bool& value)
681  {
682  std::smatch result;
683  std::regex_match(text, result, truthy_pattern);
684 
685  if (!result.empty())
686  {
687  value = true;
688  return;
689  }
690 
691  std::regex_match(text, result, falsy_pattern);
692  if (!result.empty())
693  {
694  value = false;
695  return;
696  }
697 
698  throw argument_incorrect_type(text);
699  }
700 
701  inline
702  void
703  parse_value(const std::string& text, std::string& value)
704  {
705  value = text;
706  }
707 
708  // The fallback parser. It uses the stringstream parser to parse all types
709  // that have not been overloaded explicitly. It has to be placed in the
710  // source code before all other more specialized templates.
711  template <typename T>
712  void
713  parse_value(const std::string& text, T& value)
714  {
715  stringstream_parser(text, value);
716  }
717 
718  template <typename T>
719  void
720  parse_value(const std::string& text, std::vector<T>& value)
721  {
722  T v;
723  parse_value(text, v);
724  value.push_back(v);
725  }
726 
727 #ifdef CXXOPTS_HAS_OPTIONAL
728  template <typename T>
729  void
730  parse_value(const std::string& text, std::optional<T>& value)
731  {
732  T result;
733  parse_value(text, result);
734  value = std::move(result);
735  }
736 #endif
737 
738  template <typename T>
740  {
741  static constexpr bool value = false;
742  };
743 
744  template <typename T>
745  struct type_is_container<std::vector<T>>
746  {
747  static constexpr bool value = true;
748  };
749 
750  template <typename T>
751  class abstract_value : public Value
752  {
753  using Self = abstract_value<T>;
754 
755  public:
757  : m_result(std::make_shared<T>())
758  , m_store(m_result.get())
759  {
760  }
761 
763  : m_store(t)
764  {
765  }
766 
767  virtual ~abstract_value() = default;
768 
770  {
771  if (rhs.m_result)
772  {
773  m_result = std::make_shared<T>();
774  m_store = m_result.get();
775  }
776  else
777  {
778  m_store = rhs.m_store;
779  }
780 
781  m_default = rhs.m_default;
782  m_implicit = rhs.m_implicit;
785  }
786 
787  void
788  parse(const std::string& text) const
789  {
790  parse_value(text, *m_store);
791  }
792 
793  bool
794  is_container() const
795  {
797  }
798 
799  void
800  parse() const
801  {
803  }
804 
805  bool
806  has_default() const
807  {
808  return m_default;
809  }
810 
811  bool
812  has_implicit() const
813  {
814  return m_implicit;
815  }
816 
817  std::shared_ptr<Value>
818  default_value(const std::string& value)
819  {
820  m_default = true;
822  return shared_from_this();
823  }
824 
825  std::shared_ptr<Value>
826  implicit_value(const std::string& value)
827  {
828  m_implicit = true;
830  return shared_from_this();
831  }
832 
833  std::string
835  {
836  return m_default_value;
837  }
838 
839  std::string
841  {
842  return m_implicit_value;
843  }
844 
845  bool
846  is_boolean() const
847  {
849  }
850 
851  const T&
852  get() const
853  {
854  if (m_store == nullptr)
855  {
856  return *m_result;
857  }
858  else
859  {
860  return *m_store;
861  }
862  }
863 
864  protected:
865  std::shared_ptr<T> m_result;
867 
868  bool m_default = false;
869  bool m_implicit = false;
870 
871  std::string m_default_value;
872  std::string m_implicit_value;
873  };
874 
875  template <typename T>
876  class standard_value : public abstract_value<T>
877  {
878  public:
880 
881  std::shared_ptr<Value>
882  clone() const
883  {
884  return std::make_shared<standard_value<T>>(*this);
885  }
886  };
887 
888  template <>
889  class standard_value<bool> : public abstract_value<bool>
890  {
891  public:
892  ~standard_value() = default;
893 
895  {
896  set_default_and_implicit();
897  }
898 
899  standard_value(bool* b)
900  : abstract_value(b)
901  {
902  set_default_and_implicit();
903  }
904 
905  std::shared_ptr<Value>
906  clone() const
907  {
908  return std::make_shared<standard_value<bool>>(*this);
909  }
910 
911  private:
912 
913  void
914  set_default_and_implicit()
915  {
916  m_default = true;
917  m_default_value = "false";
918  m_implicit = true;
919  m_implicit_value = "true";
920  }
921  };
922  }
923 
924  template <typename T>
925  std::shared_ptr<Value>
927  {
928  return std::make_shared<values::standard_value<T>>();
929  }
930 
931  template <typename T>
932  std::shared_ptr<Value>
933  value(T& t)
934  {
935  return std::make_shared<values::standard_value<T>>(&t);
936  }
937 
938  class OptionAdder;
939 
941  {
942  public:
944  (
945  const std::string& short_,
946  const std::string& long_,
947  const String& desc,
948  std::shared_ptr<const Value> val
949  )
950  : m_short(short_)
951  , m_long(long_)
952  , m_desc(desc)
953  , m_value(val)
954  , m_count(0)
955  {
956  }
957 
959  : m_desc(rhs.m_desc)
960  , m_count(rhs.m_count)
961  {
962  m_value = rhs.m_value->clone();
963  }
964 
965  OptionDetails(OptionDetails&& rhs) = default;
966 
967  const String&
968  description() const
969  {
970  return m_desc;
971  }
972 
973  const Value& value() const
974  {
975  return *m_value;
976  }
977 
978  std::shared_ptr<Value>
979  make_storage() const
980  {
981  return m_value->clone();
982  }
983 
984  const std::string&
985  short_name() const
986  {
987  return m_short;
988  }
989 
990  const std::string&
991  long_name() const
992  {
993  return m_long;
994  }
995 
996  private:
997  std::string m_short;
998  std::string m_long;
999  String m_desc;
1000  std::shared_ptr<const Value> m_value;
1001  int m_count;
1002  };
1003 
1005  {
1006  std::string s;
1007  std::string l;
1010  std::string default_value;
1012  std::string implicit_value;
1013  std::string arg_help;
1016  };
1017 
1019  {
1020  std::string name;
1021  std::string description;
1022  std::vector<HelpOptionDetails> options;
1023  };
1024 
1026  {
1027  public:
1028  void
1029  parse
1030  (
1031  std::shared_ptr<const OptionDetails> details,
1032  const std::string& text
1033  )
1034  {
1035  ensure_value(details);
1036  ++m_count;
1037  m_value->parse(text);
1038  }
1039 
1040  void
1041  parse_default(std::shared_ptr<const OptionDetails> details)
1042  {
1043  ensure_value(details);
1044  m_value->parse();
1045  }
1046 
1047  size_t
1048  count() const
1049  {
1050  return m_count;
1051  }
1052 
1053  template <typename T>
1054  const T&
1055  as() const
1056  {
1057  if (m_value == nullptr)
1058  {
1059  throw std::domain_error("No value");
1060  }
1061 
1062 #ifdef CXXOPTS_NO_RTTI
1063  return static_cast<const values::standard_value<T>&>(*m_value).get();
1064 #else
1065  return dynamic_cast<const values::standard_value<T>&>(*m_value).get();
1066 #endif
1067  }
1068 
1069  private:
1070  void
1071  ensure_value(std::shared_ptr<const OptionDetails> details)
1072  {
1073  if (m_value == nullptr)
1074  {
1075  m_value = details->make_storage();
1076  }
1077  }
1078 
1079  std::shared_ptr<Value> m_value;
1080  size_t m_count = 0;
1081  };
1082 
1083  class KeyValue
1084  {
1085  public:
1086  KeyValue(std::string key_, std::string value_)
1087  : m_key(std::move(key_))
1088  , m_value(std::move(value_))
1089  {
1090  }
1091 
1092  const
1093  std::string&
1094  key() const
1095  {
1096  return m_key;
1097  }
1098 
1099  const
1100  std::string&
1101  value() const
1102  {
1103  return m_value;
1104  }
1105 
1106  template <typename T>
1107  T
1108  as() const
1109  {
1110  T result;
1111  values::parse_value(m_value, result);
1112  return result;
1113  }
1114 
1115  private:
1116  std::string m_key;
1117  std::string m_value;
1118  };
1119 
1121  {
1122  public:
1123 
1124  ParseResult(
1125  const std::shared_ptr <
1126  std::unordered_map<std::string, std::shared_ptr<OptionDetails>>
1127  >,
1128  std::vector<std::string>,
1129  bool allow_unrecognised,
1130  int&, char**&);
1131 
1132  size_t
1133  count(const std::string& o) const
1134  {
1135  auto iter = m_options->find(o);
1136  if (iter == m_options->end())
1137  {
1138  return 0;
1139  }
1140 
1141  auto riter = m_results.find(iter->second);
1142 
1143  return riter->second.count();
1144  }
1145 
1146  const OptionValue&
1147  operator[](const std::string& option) const
1148  {
1149  auto iter = m_options->find(option);
1150 
1151  if (iter == m_options->end())
1152  {
1154  }
1155 
1156  auto riter = m_results.find(iter->second);
1157 
1158  return riter->second;
1159  }
1160 
1161  const std::vector<KeyValue>&
1162  arguments() const
1163  {
1164  return m_sequential;
1165  }
1166 
1167  private:
1168 
1169  void
1170  parse(int& argc, char**& argv);
1171 
1172  void
1173  add_to_option(const std::string& option, const std::string& arg);
1174 
1175  bool
1176  consume_positional(std::string a);
1177 
1178  void
1179  parse_option
1180  (
1181  std::shared_ptr<OptionDetails> value,
1182  const std::string& name,
1183  const std::string& arg = ""
1184  );
1185 
1186  void
1187  parse_default(std::shared_ptr<OptionDetails> details);
1188 
1189  void
1190  checked_parse_arg
1191  (
1192  int argc,
1193  char* argv[],
1194  int& current,
1195  std::shared_ptr<OptionDetails> value,
1196  const std::string& name
1197  );
1198 
1199  const std::shared_ptr <
1200  std::unordered_map<std::string, std::shared_ptr<OptionDetails>>
1201  > m_options;
1202  std::vector<std::string> m_positional;
1203  std::vector<std::string>::iterator m_next_positional;
1204  std::unordered_set<std::string> m_positional_set;
1205  std::unordered_map<std::shared_ptr<OptionDetails>, OptionValue> m_results;
1206 
1207  bool m_allow_unrecognised;
1208 
1209  std::vector<KeyValue> m_sequential;
1210  };
1211 
1212  class Options
1213  {
1214  typedef std::unordered_map<std::string, std::shared_ptr<OptionDetails>>
1215  OptionMap;
1216  public:
1217 
1218  Options(std::string program, std::string help_string = "")
1219  : m_program(std::move(program))
1220  , m_help_string(toLocalString(std::move(help_string)))
1221  , m_custom_help("[OPTION...]")
1222  , m_positional_help("positional parameters")
1223  , m_show_positional(false)
1224  , m_allow_unrecognised(false)
1225  , m_options(std::make_shared<OptionMap>())
1226  , m_next_positional(m_positional.end())
1227  {
1228  }
1229 
1230  Options&
1231  positional_help(std::string help_text)
1232  {
1233  m_positional_help = std::move(help_text);
1234  return *this;
1235  }
1236 
1237  Options&
1238  custom_help(std::string help_text)
1239  {
1240  m_custom_help = std::move(help_text);
1241  return *this;
1242  }
1243 
1244  Options&
1246  {
1247  m_show_positional = true;
1248  return *this;
1249  }
1250 
1251  Options&
1253  {
1254  m_allow_unrecognised = true;
1255  return *this;
1256  }
1257 
1258  ParseResult
1259  parse(int& argc, char**& argv);
1260 
1261  OptionAdder
1262  add_options(std::string group = "");
1263 
1264  void
1265  add_option
1266  (
1267  const std::string& group,
1268  const std::string& s,
1269  const std::string& l,
1270  std::string desc,
1271  std::shared_ptr<const Value> value,
1272  std::string arg_help
1273  );
1274 
1275  //parse positional arguments into the given option
1276  void
1277  parse_positional(std::string option);
1278 
1279  void
1280  parse_positional(std::vector<std::string> options);
1281 
1282  void
1283  parse_positional(std::initializer_list<std::string> options);
1284 
1285  template <typename Iterator>
1286  void
1287  parse_positional(Iterator begin, Iterator end)
1288  {
1289  parse_positional(std::vector<std::string> {begin, end});
1290  }
1291 
1292  std::string
1293  help(const std::vector<std::string>& groups = {}) const;
1294 
1295  const std::vector<std::string>
1296  groups() const;
1297 
1298  const HelpGroupDetails&
1299  group_help(const std::string& group) const;
1300 
1301  private:
1302 
1303  void
1304  add_one_option
1305  (
1306  const std::string& option,
1307  std::shared_ptr<OptionDetails> details
1308  );
1309 
1310  String
1311  help_one_group(const std::string& group) const;
1312 
1313  void
1314  generate_group_help
1315  (
1316  String& result,
1317  const std::vector<std::string>& groups
1318  ) const;
1319 
1320  void
1321  generate_all_groups_help(String& result) const;
1322 
1323  std::string m_program;
1324  String m_help_string;
1325  std::string m_custom_help;
1326  std::string m_positional_help;
1327  bool m_show_positional;
1328  bool m_allow_unrecognised;
1329 
1330  std::shared_ptr<OptionMap> m_options;
1331  std::vector<std::string> m_positional;
1332  std::vector<std::string>::iterator m_next_positional;
1333  std::unordered_set<std::string> m_positional_set;
1334 
1335  //mapping from groups to help options
1336  std::map<std::string, HelpGroupDetails> m_help;
1337  };
1338 
1340  {
1341  public:
1342 
1343  OptionAdder(Options& options, std::string group)
1344  : m_options(options), m_group(std::move(group))
1345  {
1346  }
1347 
1348  OptionAdder&
1349  operator()
1350  (
1351  const std::string& opts,
1352  const std::string& desc,
1353  std::shared_ptr<const Value> value
1354  = ::cxxopts::value<bool>(),
1355  std::string arg_help = ""
1356  );
1357 
1358  private:
1359  Options& m_options;
1360  std::string m_group;
1361  };
1362 
1363  namespace
1364  {
1365  constexpr int OPTION_LONGEST = 30;
1366  constexpr int OPTION_DESC_GAP = 2;
1367 
1368  std::basic_regex<char> option_matcher
1369  ("--([[:alnum:]][-_[:alnum:]]+)(=(.*))?|-([[:alnum:]]+)");
1370 
1371  std::basic_regex<char> option_specifier
1372  ("(([[:alnum:]]),)?[ ]*([[:alnum:]][-_[:alnum:]]*)?");
1373 
1374  String
1375  format_option
1376  (
1377  const HelpOptionDetails& o
1378  )
1379  {
1380  auto& s = o.s;
1381  auto& l = o.l;
1382 
1383  String result = " ";
1384 
1385  if (s.size() > 0)
1386  {
1387  result += "-" + toLocalString(s) + ",";
1388  }
1389  else
1390  {
1391  result += " ";
1392  }
1393 
1394  if (l.size() > 0)
1395  {
1396  result += " --" + toLocalString(l);
1397  }
1398 
1399  auto arg = o.arg_help.size() > 0 ? toLocalString(o.arg_help) : "arg";
1400 
1401  if (!o.is_boolean)
1402  {
1403  if (o.has_implicit)
1404  {
1405  result += " [=" + arg + "(=" + toLocalString(o.implicit_value) + ")]";
1406  }
1407  else
1408  {
1409  result += " " + arg;
1410  }
1411  }
1412 
1413  return result;
1414  }
1415 
1416  String
1417  format_description
1418  (
1419  const HelpOptionDetails& o,
1420  size_t start,
1421  size_t width
1422  )
1423  {
1424  auto desc = o.desc;
1425 
1426  if (o.has_default && (!o.is_boolean || o.default_value != "false"))
1427  {
1428  desc += toLocalString(" (default: " + o.default_value + ")");
1429  }
1430 
1431  String result;
1432 
1433  auto current = std::begin(desc);
1434  auto startLine = current;
1435  auto lastSpace = current;
1436 
1437  auto size = size_t{};
1438 
1439  while (current != std::end(desc))
1440  {
1441  if (*current == ' ')
1442  {
1443  lastSpace = current;
1444  }
1445 
1446  if (*current == '\n')
1447  {
1448  startLine = current + 1;
1449  lastSpace = startLine;
1450  }
1451  else if (size > width)
1452  {
1453  if (lastSpace == startLine)
1454  {
1455  stringAppend(result, startLine, current + 1);
1456  stringAppend(result, "\n");
1457  stringAppend(result, start, ' ');
1458  startLine = current + 1;
1459  lastSpace = startLine;
1460  }
1461  else
1462  {
1463  stringAppend(result, startLine, lastSpace);
1464  stringAppend(result, "\n");
1465  stringAppend(result, start, ' ');
1466  startLine = lastSpace + 1;
1467  }
1468  size = 0;
1469  }
1470  else
1471  {
1472  ++size;
1473  }
1474 
1475  ++current;
1476  }
1477 
1478  //append whatever is left
1479  stringAppend(result, startLine, current);
1480 
1481  return result;
1482  }
1483  }
1484 
1485  inline
1487  (
1488  const std::shared_ptr <
1489  std::unordered_map<std::string, std::shared_ptr<OptionDetails>>
1490  > options,
1491  std::vector<std::string> positional,
1492  bool allow_unrecognised,
1493  int& argc, char**& argv
1494  )
1495  : m_options(options)
1496  , m_positional(std::move(positional))
1497  , m_next_positional(m_positional.begin())
1498  , m_allow_unrecognised(allow_unrecognised)
1499  {
1500  parse(argc, argv);
1501  }
1502 
1503  inline
1504  OptionAdder
1505  Options::add_options(std::string group)
1506  {
1507  return OptionAdder(*this, std::move(group));
1508  }
1509 
1510  inline
1511  OptionAdder&
1512  OptionAdder::operator()
1513  (
1514  const std::string& opts,
1515  const std::string& desc,
1516  std::shared_ptr<const Value> value,
1517  std::string arg_help
1518  )
1519  {
1520  std::match_results<const char*> result;
1521  std::regex_match(opts.c_str(), result, option_specifier);
1522 
1523  if (result.empty())
1524  {
1525  throw invalid_option_format_error(opts);
1526  }
1527 
1528  const auto& short_match = result[2];
1529  const auto& long_match = result[3];
1530 
1531  if (!short_match.length() && !long_match.length())
1532  {
1533  throw invalid_option_format_error(opts);
1534  }
1535  else if (long_match.length() == 1 && short_match.length())
1536  {
1537  throw invalid_option_format_error(opts);
1538  }
1539 
1540  auto option_names = []
1541  (
1542  const std::sub_match<const char*>& short_,
1543  const std::sub_match<const char*>& long_
1544  )
1545  {
1546  if (long_.length() == 1)
1547  {
1548  return std::make_tuple(long_.str(), short_.str());
1549  }
1550  else
1551  {
1552  return std::make_tuple(short_.str(), long_.str());
1553  }
1554  }
1555  (short_match, long_match);
1556 
1557  m_options.add_option
1558  (
1559  m_group,
1560  std::get<0>(option_names),
1561  std::get<1>(option_names),
1562  desc,
1563  value,
1564  std::move(arg_help)
1565  );
1566 
1567  return *this;
1568  }
1569 
1570  inline
1571  void
1572  ParseResult::parse_default(std::shared_ptr<OptionDetails> details)
1573  {
1574  m_results[details].parse_default(details);
1575  }
1576 
1577  inline
1578  void
1579  ParseResult::parse_option
1580  (
1581  std::shared_ptr<OptionDetails> value,
1582  const std::string& /*name*/,
1583  const std::string& arg
1584  )
1585  {
1586  auto& result = m_results[value];
1587  result.parse(value, arg);
1588 
1589  m_sequential.emplace_back(value->long_name(), arg);
1590  }
1591 
1592  inline
1593  void
1594  ParseResult::checked_parse_arg
1595  (
1596  int argc,
1597  char* argv[],
1598  int& current,
1599  std::shared_ptr<OptionDetails> value,
1600  const std::string& name
1601  )
1602  {
1603  if (current + 1 >= argc)
1604  {
1605  if (value->value().has_implicit())
1606  {
1607  parse_option(value, name, value->value().get_implicit_value());
1608  }
1609  else
1610  {
1611  throw missing_argument_exception(name);
1612  }
1613  }
1614  else
1615  {
1616  if (value->value().has_implicit())
1617  {
1618  parse_option(value, name, value->value().get_implicit_value());
1619  }
1620  else
1621  {
1622  parse_option(value, name, argv[current + 1]);
1623  ++current;
1624  }
1625  }
1626  }
1627 
1628  inline
1629  void
1630  ParseResult::add_to_option(const std::string& option, const std::string& arg)
1631  {
1632  auto iter = m_options->find(option);
1633 
1634  if (iter == m_options->end())
1635  {
1636  throw option_not_exists_exception(option);
1637  }
1638 
1639  parse_option(iter->second, option, arg);
1640  }
1641 
1642  inline
1643  bool
1644  ParseResult::consume_positional(std::string a)
1645  {
1646  while (m_next_positional != m_positional.end())
1647  {
1648  auto iter = m_options->find(*m_next_positional);
1649  if (iter != m_options->end())
1650  {
1651  auto& result = m_results[iter->second];
1652  if (!iter->second->value().is_container())
1653  {
1654  if (result.count() == 0)
1655  {
1656  add_to_option(*m_next_positional, a);
1657  ++m_next_positional;
1658  return true;
1659  }
1660  else
1661  {
1662  ++m_next_positional;
1663  continue;
1664  }
1665  }
1666  else
1667  {
1668  add_to_option(*m_next_positional, a);
1669  return true;
1670  }
1671  }
1672  ++m_next_positional;
1673  }
1674 
1675  return false;
1676  }
1677 
1678  inline
1679  void
1681  {
1682  parse_positional(std::vector<std::string> {std::move(option)});
1683  }
1684 
1685  inline
1686  void
1687  Options::parse_positional(std::vector<std::string> options)
1688  {
1689  m_positional = std::move(options);
1690  m_next_positional = m_positional.begin();
1691 
1692  m_positional_set.insert(m_positional.begin(), m_positional.end());
1693  }
1694 
1695  inline
1696  void
1697  Options::parse_positional(std::initializer_list<std::string> options)
1698  {
1699  parse_positional(std::vector<std::string>(std::move(options)));
1700  }
1701 
1702  inline
1703  ParseResult
1704  Options::parse(int& argc, char**& argv)
1705  {
1706  ParseResult result(m_options, m_positional, m_allow_unrecognised, argc, argv);
1707  return result;
1708  }
1709 
1710  inline
1711  void
1712  ParseResult::parse(int& argc, char**& argv)
1713  {
1714  int current = 1;
1715 
1716  int nextKeep = 1;
1717 
1718  bool consume_remaining = false;
1719 
1720  while (current != argc)
1721  {
1722  if (strcmp(argv[current], "--") == 0)
1723  {
1724  consume_remaining = true;
1725  ++current;
1726  break;
1727  }
1728 
1729  std::match_results<const char*> result;
1730  std::regex_match(argv[current], result, option_matcher);
1731 
1732  if (result.empty())
1733  {
1734  //not a flag
1735 
1736  // but if it starts with a `-`, then it's an error
1737  if (argv[current][0] == '-' && argv[current][1] != '\0')
1738  {
1739  throw option_syntax_exception(argv[current]);
1740  }
1741 
1742  //if true is returned here then it was consumed, otherwise it is
1743  //ignored
1744  if (consume_positional(argv[current]))
1745  {
1746  }
1747  else
1748  {
1749  argv[nextKeep] = argv[current];
1750  ++nextKeep;
1751  }
1752  //if we return from here then it was parsed successfully, so continue
1753  }
1754  else
1755  {
1756  //short or long option?
1757  if (result[4].length() != 0)
1758  {
1759  const std::string& s = result[4];
1760 
1761  for (std::size_t i = 0; i != s.size(); ++i)
1762  {
1763  std::string name(1, s[i]);
1764  auto iter = m_options->find(name);
1765 
1766  if (iter == m_options->end())
1767  {
1768  if (m_allow_unrecognised)
1769  {
1770  continue;
1771  }
1772  else
1773  {
1774  //error
1775  throw option_not_exists_exception(name);
1776  }
1777  }
1778 
1779  auto value = iter->second;
1780 
1781  if (i + 1 == s.size())
1782  {
1783  //it must be the last argument
1784  checked_parse_arg(argc, argv, current, value, name);
1785  }
1786  else if (value->value().has_implicit())
1787  {
1788  parse_option(value, name, value->value().get_implicit_value());
1789  }
1790  else
1791  {
1792  //error
1793  throw option_requires_argument_exception(name);
1794  }
1795  }
1796  }
1797  else if (result[1].length() != 0)
1798  {
1799  const std::string& name = result[1];
1800 
1801  auto iter = m_options->find(name);
1802 
1803  if (iter == m_options->end())
1804  {
1805  if (m_allow_unrecognised)
1806  {
1807  // keep unrecognised options in argument list, skip to next argument
1808  argv[nextKeep] = argv[current];
1809  ++nextKeep;
1810  ++current;
1811  continue;
1812  }
1813  else
1814  {
1815  //error
1816  throw option_not_exists_exception(name);
1817  }
1818  }
1819 
1820  auto opt = iter->second;
1821 
1822  //equals provided for long option?
1823  if (result[2].length() != 0)
1824  {
1825  //parse the option given
1826 
1827  parse_option(opt, name, result[3]);
1828  }
1829  else
1830  {
1831  //parse the next argument
1832  checked_parse_arg(argc, argv, current, opt, name);
1833  }
1834  }
1835 
1836  }
1837 
1838  ++current;
1839  }
1840 
1841  for (auto& opt : *m_options)
1842  {
1843  auto& detail = opt.second;
1844  auto& value = detail->value();
1845 
1846  auto& store = m_results[detail];
1847 
1848  if (!store.count() && value.has_default())
1849  {
1850  parse_default(detail);
1851  }
1852  }
1853 
1854  if (consume_remaining)
1855  {
1856  while (current < argc)
1857  {
1858  if (!consume_positional(argv[current]))
1859  {
1860  break;
1861  }
1862  ++current;
1863  }
1864 
1865  //adjust argv for any that couldn't be swallowed
1866  while (current != argc)
1867  {
1868  argv[nextKeep] = argv[current];
1869  ++nextKeep;
1870  ++current;
1871  }
1872  }
1873 
1874  argc = nextKeep;
1875 
1876  }
1877 
1878  inline
1879  void
1881  (
1882  const std::string& group,
1883  const std::string& s,
1884  const std::string& l,
1885  std::string desc,
1886  std::shared_ptr<const Value> value,
1887  std::string arg_help
1888  )
1889  {
1890  auto stringDesc = toLocalString(std::move(desc));
1891  auto option = std::make_shared<OptionDetails>(s, l, stringDesc, value);
1892 
1893  if (s.size() > 0)
1894  {
1895  add_one_option(s, option);
1896  }
1897 
1898  if (l.size() > 0)
1899  {
1900  add_one_option(l, option);
1901  }
1902 
1903  //add the help details
1904  auto& options = m_help[group];
1905 
1906  options.options.emplace_back(HelpOptionDetails{s, l, stringDesc,
1907  value->has_default(), value->get_default_value(),
1908  value->has_implicit(), value->get_implicit_value(),
1909  std::move(arg_help),
1910  value->is_container(),
1911  value->is_boolean()});
1912  }
1913 
1914  inline
1915  void
1916  Options::add_one_option
1917  (
1918  const std::string& option,
1919  std::shared_ptr<OptionDetails> details
1920  )
1921  {
1922  auto in = m_options->emplace(option, details);
1923 
1924  if (!in.second)
1925  {
1926  throw option_exists_error(option);
1927  }
1928  }
1929 
1930  inline
1931  String
1932  Options::help_one_group(const std::string& g) const
1933  {
1934  typedef std::vector<std::pair<String, String>> OptionHelp;
1935 
1936  auto group = m_help.find(g);
1937  if (group == m_help.end())
1938  {
1939  return "";
1940  }
1941 
1942  OptionHelp format;
1943 
1944  size_t longest = 0;
1945 
1946  String result;
1947 
1948  if (!g.empty())
1949  {
1950  result += toLocalString(" " + g + " options:\n");
1951  }
1952 
1953  for (const auto& o : group->second.options)
1954  {
1955  if (o.is_container &&
1956  m_positional_set.find(o.l) != m_positional_set.end() &&
1957  !m_show_positional)
1958  {
1959  continue;
1960  }
1961 
1962  auto s = format_option(o);
1963  longest = (std::max)(longest, stringLength(s));
1964  format.push_back(std::make_pair(s, String()));
1965  }
1966 
1967  longest = (std::min)(longest, static_cast<size_t>(OPTION_LONGEST));
1968 
1969  //widest allowed description
1970  auto allowed = size_t{76} - longest - OPTION_DESC_GAP;
1971 
1972  auto fiter = format.begin();
1973  for (const auto& o : group->second.options)
1974  {
1975  if (o.is_container &&
1976  m_positional_set.find(o.l) != m_positional_set.end() &&
1977  !m_show_positional)
1978  {
1979  continue;
1980  }
1981 
1982  auto d = format_description(o, longest + OPTION_DESC_GAP, allowed);
1983 
1984  result += fiter->first;
1985  if (stringLength(fiter->first) > longest)
1986  {
1987  result += '\n';
1988  result += toLocalString(std::string(longest + OPTION_DESC_GAP, ' '));
1989  }
1990  else
1991  {
1992  result += toLocalString(std::string(longest + OPTION_DESC_GAP -
1993  stringLength(fiter->first),
1994  ' '));
1995  }
1996  result += d;
1997  result += '\n';
1998 
1999  ++fiter;
2000  }
2001 
2002  return result;
2003  }
2004 
2005  inline
2006  void
2007  Options::generate_group_help
2008  (
2009  String& result,
2010  const std::vector<std::string>& print_groups
2011  ) const
2012  {
2013  for (size_t i = 0; i != print_groups.size(); ++i)
2014  {
2015  const String& group_help_text = help_one_group(print_groups[i]);
2016  if (empty(group_help_text))
2017  {
2018  continue;
2019  }
2020  result += group_help_text;
2021  if (i < print_groups.size() - 1)
2022  {
2023  result += '\n';
2024  }
2025  }
2026  }
2027 
2028  inline
2029  void
2030  Options::generate_all_groups_help(String& result) const
2031  {
2032  std::vector<std::string> all_groups;
2033  all_groups.reserve(m_help.size());
2034 
2035  for (auto& group : m_help)
2036  {
2037  all_groups.push_back(group.first);
2038  }
2039 
2040  generate_group_help(result, all_groups);
2041  }
2042 
2043  inline
2044  std::string
2045  Options::help(const std::vector<std::string>& help_groups) const
2046  {
2047  String result = m_help_string + "\nUsage:\n " +
2048  toLocalString(m_program) + " " + toLocalString(m_custom_help);
2049 
2050  if (m_positional.size() > 0 && m_positional_help.size() > 0)
2051  {
2052  result += " " + toLocalString(m_positional_help);
2053  }
2054 
2055  result += "\n\n";
2056 
2057  if (help_groups.size() == 0)
2058  {
2059  generate_all_groups_help(result);
2060  }
2061  else
2062  {
2063  generate_group_help(result, help_groups);
2064  }
2065 
2066  return toUTF8String(result);
2067  }
2068 
2069  inline
2070  const std::vector<std::string>
2072  {
2073  std::vector<std::string> g;
2074 
2076  m_help.begin(),
2077  m_help.end(),
2078  std::back_inserter(g),
2079  [](const std::map<std::string, HelpGroupDetails>::value_type & pair)
2080  {
2081  return pair.first;
2082  }
2083  );
2084 
2085  return g;
2086  }
2087 
2088  inline
2089  const HelpGroupDetails&
2090  Options::group_help(const std::string& group) const
2091  {
2092  return m_help.at(group);
2093  }
2094 
2095 }
2096 
2097 #endif //CXXOPTS_HPP_INCLUDED
cxxopts::OptionDetails::short_name
const std::string & short_name() const
Definition: cxxopts.hpp:985
cxxopts::KeyValue::as
T as() const
Definition: cxxopts.hpp:1108
cxxopts::OptionValue
Definition: cxxopts.hpp:1025
cxxopts::option_required_exception
Definition: cxxopts.hpp:454
cxxopts::values::abstract_value::get_implicit_value
std::string get_implicit_value() const
Definition: cxxopts.hpp:840
cxxopts::OptionValue::count
size_t count() const
Definition: cxxopts.hpp:1048
cxxopts::HelpOptionDetails::s
std::string s
Definition: cxxopts.hpp:1006
cxxopts::Options::parse
ParseResult parse(int &argc, char **&argv)
Definition: cxxopts.hpp:1704
cxxopts::OptionDetails
Definition: cxxopts.hpp:940
cxxopts::OptionValue::as
const T & as() const
Definition: cxxopts.hpp:1055
cxxopts::HelpOptionDetails::arg_help
std::string arg_help
Definition: cxxopts.hpp:1013
cxxopts::values::integer_parser
void integer_parser(const std::string &text, T &value)
Definition: cxxopts.hpp:541
cxxopts::Value
Definition: cxxopts.hpp:277
cxxopts::Value::is_container
virtual bool is_container() const =0
cxxopts::OptionDetails::description
const String & description() const
Definition: cxxopts.hpp:968
cxxopts::HelpOptionDetails::has_default
bool has_default
Definition: cxxopts.hpp:1009
cxxopts::Options::add_options
OptionAdder add_options(std::string group="")
Definition: cxxopts.hpp:1505
cxxopts::values::abstract_value::abstract_value
abstract_value()
Definition: cxxopts.hpp:756
IceStorm::operator!=
bool operator!=(const IceStorm::Subscriber &, const IceStorm::Subscriber &)
Definition: Subscriber.cpp:1064
cxxopts::HelpGroupDetails::name
std::string name
Definition: cxxopts.hpp:1020
cxxopts::Options::Options
Options(std::string program, std::string help_string="")
Definition: cxxopts.hpp:1218
cxxopts::Options::show_positional_help
Options & show_positional_help()
Definition: cxxopts.hpp:1245
cxxopts::Options::parse_positional
void parse_positional(Iterator begin, Iterator end)
Definition: cxxopts.hpp:1287
cxxopts::OptionAdder
Definition: cxxopts.hpp:1339
cxxopts::argument_incorrect_type
Definition: cxxopts.hpp:440
cxxopts::Options::allow_unrecognised_options
Options & allow_unrecognised_options()
Definition: cxxopts.hpp:1252
ProsthesisInterface.values
values
Definition: ProsthesisInterface.py:190
CXXOPTS__VERSION_MINOR
#define CXXOPTS__VERSION_MINOR
Definition: cxxopts.hpp:47
cxxopts::Options::groups
const std::vector< std::string > groups() const
Definition: cxxopts.hpp:2071
detail
Definition: OpenCVUtil.cpp:127
cxxopts::HelpGroupDetails::description
std::string description
Definition: cxxopts.hpp:1021
cxxopts::OptionValue::parse
void parse(std::shared_ptr< const OptionDetails > details, const std::string &text)
Definition: cxxopts.hpp:1030
cxxopts::values::parse_value
void parse_value(const std::string &text, uint8_t &value)
Definition: cxxopts.hpp:624
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
message
message(STATUS "Boost-Library-Dir: " "${Boost_LIBRARY_DIRS}") message(STATUS "Boost-LIBRARIES
Definition: CMakeLists.txt:8
cxxopts::Value::get_implicit_value
virtual std::string get_implicit_value() const =0
cxxopts::HelpOptionDetails::implicit_value
std::string implicit_value
Definition: cxxopts.hpp:1012
cxxopts::values::checked_negate
R checked_negate(T &&t, const std::string &, std::true_type)
Definition: cxxopts.hpp:524
cxxopts::values::detail::check_signed_range
void check_signed_range(bool negative, U value, const std::string &text)
Definition: cxxopts.hpp:516
cxxopts::OptionException::OptionException
OptionException(const std::string &message)
Definition: cxxopts.hpp:321
cxxopts::Value::default_value
virtual std::shared_ptr< Value > default_value(const std::string &value)=0
cxxopts::values::detail::SignedCheck< T, false >::operator()
void operator()(bool, U, const std::string &)
Definition: cxxopts.hpp:511
cxxopts::missing_argument_exception::missing_argument_exception
missing_argument_exception(const std::string &option)
Definition: cxxopts.hpp:395
cxxopts::Value::has_default
virtual bool has_default() const =0
cxxopts::ParseResult::arguments
const std::vector< KeyValue > & arguments() const
Definition: cxxopts.hpp:1162
cxxopts::Options::group_help
const HelpGroupDetails & group_help(const std::string &group) const
Definition: cxxopts.hpp:2090
cxxopts::OptionValue::parse_default
void parse_default(std::shared_ptr< const OptionDetails > details)
Definition: cxxopts.hpp:1041
cxxopts::option_exists_error
Definition: cxxopts.hpp:355
cxxopts::patch
uint8_t patch
Definition: cxxopts.hpp:54
cxxopts::toLocalString
T toLocalString(T &&t)
Definition: cxxopts.hpp:213
cxxopts::option_not_has_argument_exception
Definition: cxxopts.hpp:414
cxxopts::empty
bool empty(const std::string &s)
Definition: cxxopts.hpp:255
IceStormElection::operator==
bool operator==(const ReplicaObserver &lhs, const ReplicaObserver &rhs)
Definition: Election.h:1599
cxxopts::KeyValue
Definition: cxxopts.hpp:1083
cxxopts::values::type_is_container
Definition: cxxopts.hpp:739
cxxopts::Options::add_option
void add_option(const std::string &group, const std::string &s, const std::string &l, std::string desc, std::shared_ptr< const Value > value, std::string arg_help)
Definition: cxxopts.hpp:1881
armarx::detail::operator*
StreamPrinter< Fnc > operator*(StreamPrinterTag, Fnc &&f)
Definition: LoggingUtil.h:44
armarx::armem::server::ltm::mongodb::util::store
void store(const mongocxx::database &db, const armem::wm::Memory &m)
Definition: operations.cpp:237
cxxopts::values::abstract_value::~abstract_value
virtual ~abstract_value()=default
cxxopts::option_not_exists_exception
Definition: cxxopts.hpp:383
cxxopts::invalid_option_format_error::invalid_option_format_error
invalid_option_format_error(const std::string &format)
Definition: cxxopts.hpp:367
cxxopts::KeyValue::value
const std::string & value() const
Definition: cxxopts.hpp:1101
cxxopts::values::stringstream_parser
void stringstream_parser(const std::string &text, T &value)
Definition: cxxopts.hpp:612
cxxopts::OptionParseException
Definition: cxxopts.hpp:346
cxxopts::values::standard_value< bool >::standard_value
standard_value(bool *b)
Definition: cxxopts.hpp:899
armarx::ctrlutil::a
double a(double t, double a0, double j)
Definition: CtrlUtil.h:45
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:926
cxxopts::HelpOptionDetails::is_container
bool is_container
Definition: cxxopts.hpp:1014
cxxopts::option_exists_error::option_exists_error
option_exists_error(const std::string &option)
Definition: cxxopts.hpp:358
cxxopts::argument_incorrect_type::argument_incorrect_type
argument_incorrect_type(const std::string &arg)
Definition: cxxopts.hpp:444
cxxopts::values::abstract_value::get_default_value
std::string get_default_value() const
Definition: cxxopts.hpp:834
cxxopts::HelpGroupDetails
Definition: cxxopts.hpp:1018
cxxopts::values::abstract_value::parse
void parse(const std::string &text) const
Definition: cxxopts.hpp:788
cxxopts::OptionDetails::OptionDetails
OptionDetails(const std::string &short_, const std::string &long_, const String &desc, std::shared_ptr< const Value > val)
Definition: cxxopts.hpp:944
cxxopts::Options::positional_help
Options & positional_help(std::string help_text)
Definition: cxxopts.hpp:1231
CXXOPTS__VERSION_PATCH
#define CXXOPTS__VERSION_PATCH
Definition: cxxopts.hpp:48
cxxopts::values::abstract_value::parse
void parse() const
Definition: cxxopts.hpp:800
cxxopts::HelpOptionDetails::desc
String desc
Definition: cxxopts.hpp:1008
cxxopts::values::abstract_value
Definition: cxxopts.hpp:751
cxxopts::values::abstract_value::m_default_value
std::string m_default_value
Definition: cxxopts.hpp:871
cxxopts::values::standard_value::clone
std::shared_ptr< Value > clone() const
Definition: cxxopts.hpp:882
cxxopts::HelpOptionDetails::is_boolean
bool is_boolean
Definition: cxxopts.hpp:1015
CXXOPTS__VERSION_MAJOR
#define CXXOPTS__VERSION_MAJOR
Definition: cxxopts.hpp:46
cxxopts::values::abstract_value::default_value
std::shared_ptr< Value > default_value(const std::string &value)
Definition: cxxopts.hpp:818
cxxopts::Value::~Value
virtual ~Value()=default
armarx::make_shared
auto make_shared(Args &&...args)
Definition: ManagedIceObject.h:90
cxxopts::OptionException
Definition: cxxopts.hpp:318
operator+
armarx::Vector3IBase operator+(const armarx::Vector3IBase &lhs, const armarx::Vector3IBase &rhs)
Definition: AStarPathPlanner.cpp:28
cxxopts::OptionAdder::OptionAdder
OptionAdder(Options &options, std::string group)
Definition: cxxopts.hpp:1343
cxxopts::option_not_exists_exception::option_not_exists_exception
option_not_exists_exception(const std::string &option)
Definition: cxxopts.hpp:386
cxxopts::HelpOptionDetails::has_implicit
bool has_implicit
Definition: cxxopts.hpp:1011
max
T max(T t1, T t2)
Definition: gdiam.h:48
cxxopts::Value::get_default_value
virtual std::string get_default_value() const =0
cxxopts::missing_argument_exception
Definition: cxxopts.hpp:392
cxxopts::Options
Definition: cxxopts.hpp:1212
cxxopts::values::abstract_value::m_implicit
bool m_implicit
Definition: cxxopts.hpp:869
cxxopts::OptionDetails::make_storage
std::shared_ptr< Value > make_storage() const
Definition: cxxopts.hpp:979
cxxopts::ParseResult::operator[]
const OptionValue & operator[](const std::string &option) const
Definition: cxxopts.hpp:1147
cxxopts::values::abstract_value::abstract_value
abstract_value(T *t)
Definition: cxxopts.hpp:762
cxxopts::values::abstract_value::m_store
T * m_store
Definition: cxxopts.hpp:866
cxxopts::option_requires_argument_exception::option_requires_argument_exception
option_requires_argument_exception(const std::string &option)
Definition: cxxopts.hpp:406
cxxopts::option_not_present_exception
Definition: cxxopts.hpp:431
cxxopts::OptionDetails::OptionDetails
OptionDetails(const OptionDetails &rhs)
Definition: cxxopts.hpp:958
cxxopts::KeyValue::KeyValue
KeyValue(std::string key_, std::string value_)
Definition: cxxopts.hpp:1086
cxxopts::values::detail::SignedCheck< T, true >::operator()
void operator()(bool negative, U u, const std::string &text)
Definition: cxxopts.hpp:487
cxxopts::values::type_is_container::value
static constexpr bool value
Definition: cxxopts.hpp:741
cxxopts::option_syntax_exception::option_syntax_exception
option_syntax_exception(const std::string &text)
Definition: cxxopts.hpp:376
cxxopts::Value::parse
virtual void parse() const =0
cxxopts::OptionSpecException::OptionSpecException
OptionSpecException(const std::string &message)
Definition: cxxopts.hpp:340
cxxopts::HelpOptionDetails::l
std::string l
Definition: cxxopts.hpp:1007
cxxopts::ParseResult::count
size_t count(const std::string &o) const
Definition: cxxopts.hpp:1133
cxxopts::values::abstract_value::m_implicit_value
std::string m_implicit_value
Definition: cxxopts.hpp:872
cxxopts::option_requires_argument_exception
Definition: cxxopts.hpp:403
option
#define option(type, fn)
cxxopts::Options::help
std::string help(const std::vector< std::string > &groups={}) const
Definition: cxxopts.hpp:2045
cxxopts::OptionDetails::long_name
const std::string & long_name() const
Definition: cxxopts.hpp:991
armarx::ctrlutil::v
double v(double t, double v0, double a0, double j)
Definition: CtrlUtil.h:39
cxxopts::values::abstract_value::m_result
std::shared_ptr< T > m_result
Definition: cxxopts.hpp:865
std
Definition: Application.h:66
cxxopts::stringLength
size_t stringLength(const String &s)
Definition: cxxopts.hpp:220
armarx::transform
auto transform(const Container< InputT, Alloc > &in, OutputT(*func)(InputT const &)) -> Container< OutputT, typename std::allocator_traits< Alloc >::template rebind_alloc< OutputT > >
Convenience function (with less typing) to transform a container of type InputT into the same contain...
Definition: algorithm.h:315
cxxopts::values::abstract_value::abstract_value
abstract_value(const abstract_value &rhs)
Definition: cxxopts.hpp:769
cxxopts::Value::is_boolean
virtual bool is_boolean() const =0
cxxopts::Options::custom_help
Options & custom_help(std::string help_text)
Definition: cxxopts.hpp:1238
cxxopts::stringAppend
String & stringAppend(String &s, String a)
Definition: cxxopts.hpp:227
cxxopts::Options::parse_positional
void parse_positional(std::string option)
Definition: cxxopts.hpp:1680
cxxopts::values::abstract_value::has_default
bool has_default() const
Definition: cxxopts.hpp:806
cxxopts::option_not_has_argument_exception::option_not_has_argument_exception
option_not_has_argument_exception(const std::string &option, const std::string &arg)
Definition: cxxopts.hpp:418
cxxopts::major
uint8_t major
Definition: cxxopts.hpp:54
cxxopts::values::abstract_value::implicit_value
std::shared_ptr< Value > implicit_value(const std::string &value)
Definition: cxxopts.hpp:826
cxxopts::invalid_option_format_error
Definition: cxxopts.hpp:364
cxxopts::value
std::shared_ptr< Value > value(T &t)
Definition: cxxopts.hpp:933
cxxopts::option_not_present_exception::option_not_present_exception
option_not_present_exception(const std::string &option)
Definition: cxxopts.hpp:434
cxxopts::HelpOptionDetails::default_value
std::string default_value
Definition: cxxopts.hpp:1010
cxxopts::Value::has_implicit
virtual bool has_implicit() const =0
cxxopts::String
std::string String
Definition: cxxopts.hpp:209
cxxopts::OptionParseException::OptionParseException
OptionParseException(const std::string &message)
Definition: cxxopts.hpp:349
cxxopts
Definition: cxxopts.hpp:50
cxxopts::option_required_exception::option_required_exception
option_required_exception(const std::string &option)
Definition: cxxopts.hpp:457
cxxopts::values::abstract_value::is_container
bool is_container() const
Definition: cxxopts.hpp:794
cxxopts::HelpOptionDetails
Definition: cxxopts.hpp:1004
cxxopts::values::standard_value
Definition: cxxopts.hpp:876
cxxopts::toUTF8String
std::string toUTF8String(T &&t)
Definition: cxxopts.hpp:248
T
float T
Definition: UnscentedKalmanFilterTest.cpp:35
min
T min(T t1, T t2)
Definition: gdiam.h:42
cxxopts::HelpGroupDetails::options
std::vector< HelpOptionDetails > options
Definition: cxxopts.hpp:1022
cxxopts::ParseResult::ParseResult
ParseResult(const std::shared_ptr< std::unordered_map< std::string, std::shared_ptr< OptionDetails >> >, std::vector< std::string >, bool allow_unrecognised, int &, char **&)
Definition: cxxopts.hpp:1487
cxxopts::OptionException::what
virtual const char * what() const noexcept
Definition: cxxopts.hpp:327
cxxopts::KeyValue::key
const std::string & key() const
Definition: cxxopts.hpp:1094
cxxopts::values::abstract_value::m_default
bool m_default
Definition: cxxopts.hpp:868
cxxopts::option_syntax_exception
Definition: cxxopts.hpp:373
cxxopts::ParseResult
Definition: cxxopts.hpp:1120
cxxopts::Value::clone
virtual std::shared_ptr< Value > clone() const =0
cxxopts::values::standard_value< bool >::standard_value
standard_value()
Definition: cxxopts.hpp:894
armarx::ctrlutil::s
double s(double t, double s0, double v0, double a0, double j)
Definition: CtrlUtil.h:33
cxxopts::values::standard_value< bool >::clone
std::shared_ptr< Value > clone() const
Definition: cxxopts.hpp:906
cxxopts::values::abstract_value::get
const T & get() const
Definition: cxxopts.hpp:852
cxxopts::OptionDetails::value
const Value & value() const
Definition: cxxopts.hpp:973
cxxopts::values::detail::SignedCheck
Definition: cxxopts.hpp:480
cxxopts::values::abstract_value::is_boolean
bool is_boolean() const
Definition: cxxopts.hpp:846
cxxopts::values::abstract_value::has_implicit
bool has_implicit() const
Definition: cxxopts.hpp:812
cxxopts::minor
uint8_t minor
Definition: cxxopts.hpp:54
cxxopts::Value::implicit_value
virtual std::shared_ptr< Value > implicit_value(const std::string &value)=0
cxxopts::OptionSpecException
Definition: cxxopts.hpp:336