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