vSMC
vSMC: Scalable Monte Carlo
program_option.hpp
Go to the documentation of this file.
1 //============================================================================
2 // vSMC/include/vsmc/utility/program_option.hpp
3 //----------------------------------------------------------------------------
4 // vSMC: Scalable Monte Carlo
5 //----------------------------------------------------------------------------
6 // Copyright (c) 2013,2014, Yan Zhou
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are met:
11 //
12 // Redistributions of source code must retain the above copyright notice,
13 // this list of conditions and the following disclaimer.
14 //
15 // Redistributions in binary form must reproduce the above copyright notice,
16 // this list of conditions and the following disclaimer in the documentation
17 // and/or other materials provided with the distribution.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 // POSSIBILITY OF SUCH DAMAGE.
30 //============================================================================
31 
207 
208 #ifndef VSMC_UTILITY_PROGRAM_OPTION_HPP
209 #define VSMC_UTILITY_PROGRAM_OPTION_HPP
210 
211 #include <vsmc/internal/common.hpp>
212 
213 #define VSMC_RUNTIME_ASSERT_UTILITY_PROGRAM_OPTION_NULLPTR(ptr, func) \
214  VSMC_RUNTIME_ASSERT((ptr != VSMC_NULLPTR), \
215  ("**ProgramOptionMap::"#func \
216  "** ATTEMPT TO SET OPTION WITH A NULL POINTER"))
217 
218 namespace vsmc {
219 
222 inline void program_option_warning (const std::string &oname,
223  const std::string &msg, bool silent, std::ostream &os)
224 {
225  if (silent)
226  return;
227 
228  os << "vSMC Program Option Warning\n";
229  os << "Option: " << oname << '\n';
230  os << "Message : " << msg << std::endl;
231 }
232 
236 {
237  public :
238 
241  ProgramOption &operator= (const ProgramOption &) {return *this;}
242  virtual ~ProgramOption () {}
243 
244  virtual bool is_bool () const = 0;
245  virtual bool is_vector () const = 0;
246  virtual bool set (const std::string &, const std::string &, bool,
247  std::ostream &) = 0;
248  virtual bool set_default () = 0;
249  virtual std::string description () const = 0;
250  virtual std::string default_str () const = 0;
251  virtual ProgramOption *clone () const = 0;
252 
253  protected :
254 
255  bool set_value (const std::string &oname, const std::string &sval,
256  bool *dest, bool silent, std::ostream &os)
257  {
258  const char *const sptr = sval.c_str();
259  const std::size_t size = sval.size();
260 
261  bool is_numb = true;
262  bool is_zero = true;
263  for (std::size_t i = 0; i != size; ++i) {
264  char c = sptr[i];
265  is_numb = is_numb && c >= '0' && c <= '9';
266  is_zero = is_zero && (c == '0');
267  }
268  if (is_zero) {
269  *dest = false;
270  return true;
271  } else if (is_numb) {
272  *dest = true;
273  return true;
274  }
275 
276  bool is_true = false;
277  is_true = is_true || std::strcmp(sptr, "y") == 0;
278  is_true = is_true || std::strcmp(sptr, "Y") == 0;
279  is_true = is_true || std::strcmp(sptr, "yes") == 0;
280  is_true = is_true || std::strcmp(sptr, "Yes") == 0;
281  is_true = is_true || std::strcmp(sptr, "YES") == 0;
282  is_true = is_true || std::strcmp(sptr, "t") == 0;
283  is_true = is_true || std::strcmp(sptr, "T") == 0;
284  is_true = is_true || std::strcmp(sptr, "true") == 0;
285  is_true = is_true || std::strcmp(sptr, "True") == 0;
286  is_true = is_true || std::strcmp(sptr, "TRUE") == 0;
287  if (is_true) {
288  *dest = true;
289  return true;
290  }
291 
292  bool is_false = false;
293  is_false = is_false || std::strcmp(sptr, "n") == 0;
294  is_false = is_false || std::strcmp(sptr, "N") == 0;
295  is_false = is_false || std::strcmp(sptr, "no") == 0;
296  is_false = is_false || std::strcmp(sptr, "No") == 0;
297  is_false = is_false || std::strcmp(sptr, "NO") == 0;
298  is_false = is_false || std::strcmp(sptr, "f") == 0;
299  is_false = is_false || std::strcmp(sptr, "F") == 0;
300  is_false = is_false || std::strcmp(sptr, "false") == 0;
301  is_false = is_false || std::strcmp(sptr, "False") == 0;
302  is_false = is_false || std::strcmp(sptr, "FALSE") == 0;
303  if (is_false) {
304  *dest = false;
305  return true;
306  }
307 
308  program_option_warning(oname, "Failed to set value: " + sval,
309  silent, os);
310  return false;
311  }
312 
313  template <typename T>
314  bool set_value (const std::string &oname, const std::string &sval,
315  T *dest, bool silent, std::ostream &os)
316  {
317  std::stringstream ss;
318  ss.str(sval);
319  T tval;
320  ss >> tval;
321  if (ss.fail()) {
322  program_option_warning(oname, "Failed to set value: " + sval,
323  silent, os);
324  ss.clear();
325  return false;
326  }
327 #if VSMC_HAS_CXX11_RVALUE_REFERENCES
328  *dest = cxx11::move(tval);
329 #else
330  *dest = tval;
331 #endif
332 
333  return true;
334  }
335 }; // class ProgramOption
336 
340 {
341  public :
342 
343  ProgramOptionHelp () : help_(false) {}
344 
345  bool is_bool () const {return true;}
346 
347  bool is_vector () const {return false;}
348 
349  bool set (const std::string &oname, const std::string &sval, bool silent,
350  std::ostream &os)
351  {return set_value(oname, sval, &help_, silent, os);}
352 
353  bool set_default () {return false;}
354 
355  std::string description () const
356  {return std::string("Print this help information");}
357 
358  std::string default_str () const
359  {return std::string("(false)");}
360 
361  ProgramOption *clone () const {return new ProgramOptionHelp;}
362 
363  bool help () const {return help_;}
364 
365  private :
366 
367  bool help_;
368 }; // ProgramOptionHelp
369 
372 template <typename T>
374 {
375  public :
376 
377  ProgramOptionDefault (const std::string &desc) :
378  desc_(desc), default_(T()), has_default_(false) {}
379 
380  template <typename V>
381  ProgramOptionDefault (const std::string &desc, V val) :
382  desc_(desc), default_(static_cast<T>(val)), has_default_(true) {}
383 
384  bool is_bool () const {return cxx11::is_same<T, bool>::value;}
385 
386  std::string description () const {return desc_;}
387 
388  std::string default_str () const
389  {return has_default_ ? default_val2str(default_) : std::string();}
390 
391  protected :
392 
393  bool set_value_default (T *dest)
394  {
395  if (has_default_)
396  *dest = default_;
397 
398  return has_default_;
399  }
400 
401  private :
402 
403  std::string desc_;
404  T default_;
405  bool has_default_;
406 
407  template <typename U>
408  std::string default_val2str (const U &val) const
409  {
410  std::stringstream ss;
411  ss << '(' << val << ')';
412 
413  return ss.str();
414  }
415 
416  std::string default_val2str (bool val) const
417  {return val ? std::string("(true)") : std::string("(false)");}
418 }; // ProgramOptionDefault
419 
422 template <typename T>
424 {
425  public :
426 
427  ProgramOptionScalar (const std::string &desc, T *ptr) :
428  ProgramOptionDefault<T>(desc), ptr_(ptr) {}
429 
430  template <typename V>
431  ProgramOptionScalar (const std::string &desc, T *ptr, V val) :
432  ProgramOptionDefault<T>(desc, val), ptr_(ptr) {}
433 
434  bool is_vector () const {return false;}
435 
436  bool set (const std::string &oname, const std::string &sval, bool silent,
437  std::ostream &os)
438  {return this->set_value(oname, sval, ptr_, silent, os);}
439 
440  bool set_default () {return this->set_value_default(ptr_);}
441 
443  {return new ProgramOptionScalar<T>(*this);}
444 
445  private :
446 
447  T *const ptr_;
448 }; // class ProgramOptionScalar
449 
452 template <typename T>
454 {
455  public :
456 
457  ProgramOptionVector (const std::string &desc, std::vector<T> *ptr) :
458  ProgramOptionDefault<T>(desc), val_(T()), ptr_(ptr) {}
459 
460  template <typename V>
461  ProgramOptionVector (const std::string &desc, std::vector<T> *ptr, V val) :
462  ProgramOptionDefault<T>(desc, val), val_(T()), ptr_(ptr) {}
463 
464  bool is_vector () const {return true;}
465 
466  bool set (const std::string &oname, const std::string &sval, bool silent,
467  std::ostream &os)
468  {
469  bool success = this->set_value(oname, sval, &val_, silent, os);
470 
471  if (success)
472  ptr_->push_back(val_);
473 
474  return success;
475  }
476 
477  bool set_default ()
478  {
479  bool success = this->set_value_default(&val_);
480 
481  if (success)
482  ptr_->push_back(val_);
483 
484  return success;
485  }
486 
487  ProgramOption *clone () const {return new ProgramOptionVector<T>(*this);}
488 
489  private :
490 
491  T val_;
492  std::vector<T> *const ptr_;
493 }; // class ProgramOptionVector
494 
498 {
499  typedef std::map<std::string, std::pair<ProgramOption *, std::size_t> >
500  option_map_type;
501  typedef std::list<std::pair<std::string, const ProgramOption *> >
502  option_list_type;
503 
504  public :
505 
506  explicit ProgramOptionMap (bool silent = false, bool auto_help = true) :
507  silent_(silent), auto_help_(auto_help),
508  help_ptr_(new ProgramOptionHelp)
509  {
510  option_map_["--help"] = std::make_pair(help_ptr_, 0);
511  option_list_.push_back(std::make_pair("--help", help_ptr_));
512  }
513 
515  silent_(other.silent_), auto_help_(other.auto_help_),
516  option_map_(other.option_map_), option_list_(other.option_list_)
517  {
518  for (option_map_type::iterator iter = option_map_.begin();
519  iter != option_map_.end(); ++iter) {
520  if (iter->second.first)
521  iter->second.first = iter->second.first->clone();
522  }
523  }
524 
526  {
527  if (this != &other) {
528  silent_ = other.silent_;
529  auto_help_ = other.auto_help_;
530  for (option_map_type::iterator iter = option_map_.begin();
531  iter != option_map_.end(); ++iter) {
532  if (iter->second.first)
533  delete iter->second.first;
534  }
535 
536  option_map_ = other.option_map_;
537  option_list_ = other.option_list_;
538 
539  for (option_map_type::iterator iter = option_map_.begin();
540  iter != option_map_.end(); ++iter) {
541  if (iter->second.first)
542  iter->second.first = iter->second.first->clone();
543  }
544  }
545 
546  return *this;
547  }
548 
549 #if VSMC_HAS_CXX11_RVALUE_REFERENCES
551  silent_(other.silent_), auto_help_(other.auto_help_),
552  help_ptr_(other.help_ptr_),
553  option_map_(cxx11::move(other.option_map_)),
554  option_list_(cxx11::move(other.option_list_))
555  {
556  other.help_ptr_ = VSMC_NULLPTR;
557  other.option_map_.clear();
558  other.option_list_.clear();
559  }
560 
562  {
563  if (this != &other) {
564  silent_ = other.silent_;
565  help_ptr_ = other.help_ptr_;
566  option_map_ = cxx11::move(other.option_map_);
567  option_list_ = cxx11::move(other.option_list_);
568  other.help_ptr_ = VSMC_NULLPTR;
569  other.option_map_.clear();
570  other.option_list_.clear();
571  }
572 
573  return *this;
574  }
575 #endif
576 
578  {
579  for (option_map_type::iterator iter = option_map_.begin();
580  iter != option_map_.end(); ++iter) {
581  if (iter->second.first != VSMC_NULLPTR)
582  delete iter->second.first;
583  }
584  }
585 
592  template <typename T>
593  ProgramOptionMap &add (const std::string &name, const std::string &desc,
594  T *ptr)
595  {
597  const std::string oname("--" + name);
598  ProgramOption *optr = new ProgramOptionScalar<T>(desc, ptr);
599  add_option(oname, optr);
600 
601  return *this;
602  }
603 
605  template <typename T, typename V>
606  ProgramOptionMap &add (const std::string &name, const std::string &desc,
607  T *ptr, V val)
608  {
610  const std::string oname("--" + name);
611  ProgramOption *optr = new ProgramOptionScalar<T>(desc, ptr, val);
612  add_option(oname, optr);
613 
614  return *this;
615  }
616 
618  template <typename T>
619  ProgramOptionMap &add (const std::string &name, const std::string &desc,
620  std::vector<T> *ptr)
621  {
623  const std::string oname("--" + name);
624  ProgramOption *optr = new ProgramOptionVector<T>(desc, ptr);
625  add_option(oname, optr);
626 
627  return *this;
628  }
629 
631  template <typename T, typename V>
632  ProgramOptionMap &add (const std::string &name, const std::string &desc,
633  std::vector<T> *ptr, V val)
634  {
636  const std::string oname("--" + name);
637  ProgramOption *optr = new ProgramOptionVector<T>(desc, ptr, val);
638  add_option(oname, optr);
639 
640  return *this;
641  }
642 
643  ProgramOptionMap &remove (const std::string &name)
644  {
645  const std::string oname("--" + name);
646  option_map_type::iterator iter = option_map_.find(oname);
647  if (iter != option_map_.end()) {
648  if (iter->second.first != VSMC_NULLPTR)
649  delete iter->second.first;
650  option_map_.erase(iter);
651  option_list_type::iterator liter = option_list_find(oname);
652  option_list_.erase(liter);
653  }
654 
655  return *this;
656  }
657 
669  void process (int argc, const char **argv, std::ostream &os = std::cout)
670  {
671  std::string arg;
672  std::vector<std::string> arg_vector;
673  arg_vector.reserve(static_cast<std::size_t>(argc));
674  for (int i = 0; i != argc; ++i) {
675  arg = process_arg(argv[i]);
676  if (!arg.empty())
677  arg_vector.push_back(arg);
678  }
679  process_arg_vector(arg_vector, os);
680  }
681 
683  void process (int argc, char **argv, std::ostream &os = std::cout)
684  {
685  std::string arg;
686  std::vector<std::string> arg_vector;
687  arg_vector.reserve(static_cast<std::size_t>(argc));
688  for (int i = 0; i != argc; ++i) {
689  arg = process_arg(argv[i]);
690  if (!arg.empty())
691  arg_vector.push_back(arg);
692  }
693  process_arg_vector(arg_vector, os);
694  }
695 
697  void print_help (std::ostream &os = std::cout) const
698  {
699  std::size_t len[2] = {0, 0};
700  std::vector<std::string> vec[3];
701  for (option_list_type::const_iterator liter = option_list_.begin();
702  liter != option_list_.end(); ++liter) {
703  vec[0].push_back(liter->first);
704  vec[1].push_back(liter->second->description());
705  vec[2].push_back(liter->second->default_str());
706  if (len[0] < vec[0].back().size())
707  len[0] = vec[0].back().size();
708  if (len[1] < vec[1].back().size())
709  len[1] = vec[1].back().size();
710  }
711  len[0] += 4;
712  len[1] += 4;
713  for (std::size_t i = 0; i != vec[0].size(); ++i) {
714  os << vec[0][i] << std::string(len[0] - vec[0][i].size(), ' ');
715  os << vec[1][i] << std::string(len[1] - vec[1][i].size(), ' ');
716  os << vec[2][i] << std::endl;
717  }
718  }
719 
721  std::size_t count (const std::string &name) const
722  {
723  option_map_type::const_iterator iter = option_map_.find("--" + name);
724  if (iter != option_map_.end())
725  return iter->second.second;
726  else
727  return 0;
728  }
729 
731  const ProgramOption *option (const std::string &name) const
732  {
733  option_map_type::const_iterator iter = option_map_.find("--" + name);
734  if (iter != option_map_.end())
735  return iter->second.first;
736  else
737  return VSMC_NULLPTR;
738  }
739 
741  ProgramOption *option (const std::string &name)
742  {
743  option_map_type::const_iterator iter = option_map_.find("--" + name);
744  if (iter != option_map_.end())
745  return iter->second.first;
746  else
747  return VSMC_NULLPTR;
748  }
749 
752  void silent (bool flag) {silent_ = flag;}
753 
756  void auto_help (bool flag) {auto_help_ = flag;}
757 
758  private :
759 
760  bool silent_;
761  bool auto_help_;
762  ProgramOptionHelp *help_ptr_;
763  option_map_type option_map_;
764  option_list_type option_list_;
765 
766  option_list_type::iterator option_list_find (const std::string &oname)
767  {
768  option_list_type::iterator liter = option_list_.begin();
769  for (; liter != option_list_.end(); ++liter) {
770  if (liter->first == oname)
771  break;
772  }
773 
774  return liter;
775  }
776 
777  void add_option (const std::string &oname, ProgramOption *optr)
778  {
779  std::pair<option_map_type::iterator, bool> insert =
780  option_map_.insert(std::make_pair(oname, std::make_pair(optr, 0)));
781  if (insert.second) {
782  option_list_.push_back(std::make_pair(oname, optr));
783  } else {
784  if (insert.first->second.first != VSMC_NULLPTR)
785  delete insert.first->second.first;
786  insert.first->second.first = optr;
787  option_list_type::iterator liter = option_list_find(oname);
788  liter->second = optr;
789  }
790  }
791 
792  void process_arg_vector (std::vector<std::string> &arg_vector,
793  std::ostream &os)
794  {
795  std::string option_value;
796  const std::vector<std::string> option_value_vec;
797  std::vector<std::pair<std::string, std::vector<std::string> > >
798  option_vector;
799  std::vector<std::string>::iterator aiter = arg_vector.begin();
800  while (aiter != arg_vector.end() && !is_option(*aiter))
801  ++aiter;
802  while (aiter != arg_vector.end()) {
803  option_vector.push_back(std::make_pair(*aiter, option_value_vec));
804  std::vector<std::string> &value = option_vector.back().second;
805  ++aiter;
806  while (aiter != arg_vector.end() &&!is_option(*aiter)) {
807  value.push_back(*aiter);
808  ++aiter;
809  }
810  }
811 
812  const std::string sval_true("1");
813  for (std::vector<std::pair<std::string, std::vector<std::string> > >::
814  iterator iter = option_vector.begin();
815  iter != option_vector.end(); ++iter) {
816  option_map_type::iterator miter = option_map_.find(iter->first);
817  if (miter == option_map_.end()) {
818  program_option_warning(iter->first, "Unknown option",
819  silent_, os);
820  continue;
821  }
822 
823  bool proc = false;
824  const std::size_t vsize = iter->second.size();
825  if (vsize == 0 && miter->second.first->is_bool()) {
826  proc = process_option(miter, sval_true, os);
827  } else if (vsize == 0) {
828  program_option_warning(miter->first, "Value not found",
829  silent_, os);
830  } else if (!miter->second.first->is_vector()) {
831  option_value.clear();
832  for (std::size_t i = 0; i != vsize - 1; ++i)
833  option_value += iter->second[i] + ' ';
834  option_value += iter->second[vsize - 1];
835  proc = process_option(miter, option_value, os);
836  } else {
837  for (std::size_t i = 0; i != vsize; ++i)
838  proc = process_option(miter, iter->second[i], os) || proc;
839  }
840  if (proc)
841  ++miter->second.second;
842  }
843 
844  for (option_map_type::iterator iter = option_map_.begin();
845  iter != option_map_.end(); ++iter) {
846  if (iter->second.second == 0)
847  if (iter->second.first->set_default())
848  iter->second.second = 1;
849  }
850 
851  if (auto_help_ && help_ptr_->help())
852  print_help(os);
853  }
854 
855  std::string process_arg (const char *arg) const
856  {
857  std::size_t s = std::strlen(arg);
858  std::size_t e = s;
859  while (e != 0 && (arg[e - 1] == ' ' || arg[e - 1] == ','))
860  --e;
861 
862  return std::string(arg, arg + e);
863  }
864 
865  bool process_option (option_map_type::iterator iter,
866  const std::string &sval, std::ostream &os)
867  {
868  if (sval.empty()) {
869  program_option_warning(iter->first, "No value found", silent_, os);
870  return false;
871  }
872 
873  return iter->second.first->set(iter->first, sval, silent_, os);
874  }
875 
876  bool is_option (const std::string &str) const
877  {
878  if (str.size() < 3)
879  return false;
880 
881  if (str[0] != '-')
882  return false;
883 
884  if (str[1] != '-')
885  return false;
886 
887  return true;
888  }
889 }; // class ProgramOptionMap
890 
891 } // namespace vsmc
892 
893 #endif // VSMC_UTILITY_PROGRAM_OPTION_HPP
ProgramOption & operator=(const ProgramOption &)
Definition: adapter.hpp:37
virtual bool set_default()=0
ProgramOptionMap(bool silent=false, bool auto_help=true)
std::string default_str() const
bool set(const std::string &oname, const std::string &sval, bool silent, std::ostream &os)
ProgramOption * option(const std::string &name)
Get the underlying option object.
ProgramOptionMap & add(const std::string &name, const std::string &desc, T *ptr)
Add an option with a single value.
virtual ProgramOption * clone() const =0
A map of ProgramOption.
ProgramOptionMap & operator=(const ProgramOptionMap &other)
ProgramOptionDefault(const std::string &desc)
STL namespace.
ProgramOption * clone() const
std::string description() const
ProgramOption(const ProgramOption &)
virtual bool is_vector() const =0
void silent(bool flag)
Set the silent flag, if true, no warning messages will be printed for unknown options etc...
void process(int argc, const char **argv, std::ostream &os=std::cout)
Process the options.
ProgramOptionScalar(const std::string &desc, T *ptr)
ProgramOptionScalar(const std::string &desc, T *ptr, V val)
ProgramOptionDefault(const std::string &desc, V val)
ProgramOptionVector(const std::string &desc, std::vector< T > *ptr)
ProgramOption * clone() const
Option with multiple values.
void program_option_warning(const std::string &oname, const std::string &msg, bool silent, std::ostream &os)
Program option warning messages.
Program option base class.
ProgramOptionMap(const ProgramOptionMap &other)
bool set_value(const std::string &oname, const std::string &sval, bool *dest, bool silent, std::ostream &os)
Option with a single value.
ProgramOptionMap & add(const std::string &name, const std::string &desc, std::vector< T > *ptr, V val)
Add an option with multiple value, with a default value.
remove_reference< T >::type && move(T &&t) noexcept
#define VSMC_NULLPTR
nullptr
Definition: defines.hpp:79
ProgramOption * clone() const
virtual bool set(const std::string &, const std::string &, bool, std::ostream &)=0
#define VSMC_RUNTIME_ASSERT_UTILITY_PROGRAM_OPTION_NULLPTR(ptr, func)
const ProgramOption * option(const std::string &name) const
Get the underlying option object.
std::string default_str() const
virtual bool is_bool() const =0
void print_help(std::ostream &os=std::cout) const
Print help information for each option.
ProgramOptionMap & add(const std::string &name, const std::string &desc, std::vector< T > *ptr)
Add an option with multiple value.
virtual std::string default_str() const =0
void process(int argc, char **argv, std::ostream &os=std::cout)
Process the options.
virtual std::string description() const =0
Option with a default value.
std::size_t count(const std::string &name) const
Count the number of successful processing of an option.
ProgramOptionMap & add(const std::string &name, const std::string &desc, T *ptr, V val)
Add an option with a single value, with a default value.
ProgramOptionVector(const std::string &desc, std::vector< T > *ptr, V val)
bool set(const std::string &oname, const std::string &sval, bool silent, std::ostream &os)
bool set(const std::string &oname, const std::string &sval, bool silent, std::ostream &os)
bool set_value(const std::string &oname, const std::string &sval, T *dest, bool silent, std::ostream &os)
ProgramOptionMap(ProgramOptionMap &&other)
std::string description() const
void auto_help(bool flag)
Set the auto_help flag, if true, help information is printed automatically when the --help option is ...