Limbo
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ProgramOptions.h
Go to the documentation of this file.
1 
11 #ifndef _LIMBO_PROGRAMOPTIONS_PROGRAMOPTIONS_H
12 #define _LIMBO_PROGRAMOPTIONS_PROGRAMOPTIONS_H
13 
14 #include <iostream>
15 #include <sstream>
16 #include <vector>
17 #include <string>
18 #include <map>
19 #include <exception>
20 #include <limbo/string/String.h>
23 
25 namespace limbo
26 {
28 namespace programoptions
29 {
30 
35 class ProgramOptionsException : public std::exception
36 {
37  public:
39  typedef std::exception base_type;
44  ProgramOptionsException(std::string const& msg) : base_type(), m_msg(msg) {}
49  ProgramOptionsException(ProgramOptionsException const& rhs) : base_type(rhs), m_msg(rhs.m_msg) {}
53  virtual ~ProgramOptionsException() throw() {}
58  virtual const char* what() const throw () {return m_msg.c_str();}
59  protected:
60  std::string m_msg;
61 };
62 
67 class ValueBase
68 {
69  public:
75  ValueBase(std::string const& cat, std::string const& m)
76  : m_category(cat)
77  , m_msg(m)
78  , m_help(false)
79  , m_required(false)
80  , m_valid(false)
81  , m_toggle(false)
82  {}
87  ValueBase(ValueBase const& rhs) {copy(rhs);}
94  {
95  if (this != &rhs)
96  copy(rhs);
97  return *this;
98  }
102  virtual ~ValueBase() {}
103 
105 
109  virtual bool parse(const char*) = 0;
114  virtual void print(std::ostream& os) const = 0;
119  virtual void print_default(std::ostream& os) const = 0;
123  virtual void apply_default() = 0;
127  virtual void apply_toggle() = 0;
132  virtual bool valid_target() const = 0;
137  virtual bool valid_default() const = 0;
142  virtual bool valid_toggle() const = 0;
147  virtual unsigned count_default_chars() const = 0;
152  virtual bool help_on() const = 0;
153 
157  std::string const& category() const {return m_category;}
161  std::string const& msg() const {return m_msg;}
165  bool help() const {return m_help;}
169  bool required() const {return m_required;}
173  bool valid() const {return m_valid;}
177  bool toggle() const {return m_toggle;}
182  void print_category(std::ostream& os) const {os << category();}
187  void print_msg(std::ostream& os) const {os << msg();}
188  protected:
193  void copy(ValueBase const& rhs)
194  {
195  m_category = rhs.m_category;
196  m_msg = rhs.m_msg;
197  m_help = rhs.m_help;
198  m_required = rhs.m_required;
199  m_valid = rhs.m_valid;
200  m_toggle = rhs.m_toggle;
201  }
202 
203  std::string m_category;
204  std::string m_msg;
205  unsigned char m_help : 1;
206  unsigned char m_required : 1;
207  unsigned char m_valid : 1;
208  unsigned char m_toggle : 1;
209 };
210 
216 template <typename T>
217 class Value : public ValueBase
218 {
219  public:
221  typedef T value_type;
224 
231  Value(std::string const& cat, value_type* target, std::string const& m)
232  : base_type(cat, m)
233  , m_target(target)
234  , m_default_value(NULL)
235  , m_toggle_value(NULL)
236  , m_default_display("")
237  {}
242  Value(Value const& rhs)
243  : base_type(rhs)
244  {
245  copy(rhs);
246  }
252  Value& operator=(Value const& rhs)
253  {
254  if (this != &rhs)
255  {
256  this->base_type::copy(rhs);
257  this->copy(rhs);
258  }
259  return *this;
260  }
264  virtual ~Value()
265  {
266  if (m_default_value)
267  delete m_default_value;
268  if (m_toggle_value)
269  delete m_toggle_value;
270  }
271 
277  virtual bool parse(const char* v)
278  {
279  if (m_target)
280  {
281  bool flag = parse_helper<value_type>()(*m_target, v);
282  if (flag)
283  m_valid = true;
284  return flag;
285  }
286  return false;
287  }
292  virtual void print(std::ostream& os) const
293  {
294  if (m_target)
296  }
301  virtual void print_default(std::ostream& os) const
302  {
303  if (m_default_value)
304  {
305  if (m_default_display.empty())
307  else os << m_default_display;
308  }
309  }
313  virtual void apply_default()
314  {
315  if (m_target && m_default_value)
317  }
321  virtual void apply_toggle()
322  {
323  if (m_target && m_toggle_value)
324  {
326  m_valid = true;
327  }
328  }
333  virtual bool valid_target() const
334  {
335  return (m_target != NULL);
336  }
341  virtual bool valid_default() const
342  {
343  return (m_default_value != NULL);
344  }
349  virtual bool valid_toggle() const
350  {
351  return (m_toggle_value != NULL);
352  }
357  virtual unsigned count_default_chars() const
358  {
359  std::ostringstream oss;
360  print_default(oss);
361  return oss.str().size();
362  }
367  virtual bool help_on() const
368  {
369  // only true when this option is already set
371  return true;
372  else return false;
373  }
380  virtual Value& default_value(value_type const& v, std::string const& d = "")
381  {
382  if (m_default_value) // in case for multiple calls
383  delete m_default_value;
384  m_default_value = new value_type (v);
385  m_default_display = d;
386  return *this;
387  }
393  virtual Value& toggle_value(value_type const& v)
394  {
395  if (m_toggle_value) // in case for multiple calls
396  delete m_toggle_value;
397  m_toggle_value = new value_type (v);
398  return *this;
399  }
405  virtual Value& help(bool h)
406  {
407  m_help = h;
408  return *this;
409  }
415  virtual Value& required(bool r)
416  {
417  m_required = r;
418  return *this;
419  }
425  virtual Value& toggle(bool t)
426  {
427  m_toggle = t;
428  return *this;
429  }
430 
431  protected:
436  void copy(Value const& rhs)
437  {
438  m_target = rhs.m_target;
439  m_default_value = NULL;
440  m_toggle_value = NULL;
441  if (rhs.m_default_value)
443  if (rhs.m_toggle_value)
445  }
446 
447  value_type* m_target;
448  value_type* m_default_value;
449  value_type* m_toggle_value;
450  std::string m_default_display;
451 };
452 
458 {
459  public:
461  typedef std::map<std::string, unsigned> cat2index_map_type;
462 
467  ProgramOptions(std::string const& title = "Available options");
472  ProgramOptions(ProgramOptions const& rhs);
476  ~ProgramOptions();
477 
483  template <typename ValueType>
484  ProgramOptions& add_option(ValueType const& data);
490  bool parse(int argc, char** argv);
491 
495  bool count(std::string const& cat) const;
496 
500  void print() const {print(std::cout);}
505  void print(std::ostream& os) const;
512  friend std::ostream& operator<<(std::ostream& os, ProgramOptions const& rhs)
513  {
514  rhs.print(os);
515  return os;
516  }
517  protected:
521  inline void print_space(std::ostream& os, unsigned num) const
522  {
523  assert_msg(num < 1000, "num out of bounds: " << num);
524  os << std::string (num, ' ');
525  }
526 
527  std::map<std::string, unsigned> m_mCat2Index;
528  std::vector<ValueBase*> m_vData;
529  std::string m_title;
530 };
531 
532 inline ProgramOptions::ProgramOptions(std::string const& title)
533  : m_title(title)
534 {}
535 
536 template <typename ValueType>
538 {
539  std::pair<cat2index_map_type::iterator, bool> insertRet = m_mCat2Index.insert(std::make_pair(data.category(), m_vData.size()));
540  if (insertRet.second) // only create new data when it is not in the map
541  m_vData.push_back(new ValueType (data));
542  return *this;
543 }
544 
545 } // programoptions
546 } // namespace limbo
547 
548 #endif
std::map< std::string, unsigned > m_mCat2Index
saving mapping for flag to option
Value(Value const &rhs)
copy constructor
std::string m_msg
message of the exception
std::vector< ValueBase * > m_vData
saving options
Value(std::string const &cat, value_type *target, std::string const &m)
constructor
unsigned char m_toggle
true if this option is a toggle value
ProgramOptionsException(std::string const &msg)
constructor
metafunction for parsing a char-based string to a target data type
std::map< std::string, unsigned > cat2index_map_type
mapping from category to index
virtual ~ValueBase()
destructor
ValueBase base_type
base type
ValueBase(ValueBase const &rhs)
copy constructor
std::string m_default_display
display default value
virtual bool parse(const char *v)
parse data from string
void copy(ValueBase const &rhs)
copy another object
abstract type of data value which defines various virtual functions
virtual bool valid_target() const
check whether target value is valid
virtual bool valid_default() const
check whether default value is valid
assertion with message
unsigned char m_valid
true if target is set, not default
virtual bool valid_target() const =0
check whether target value is valid
friend std::ostream & operator<<(std::ostream &os, ProgramOptions const &rhs)
print help message by override operator<<
virtual const char * what() const
access message
helper function objects for various data types
metafunction for printing a target data type
virtual bool valid_toggle() const =0
check whether toggle value is valid
virtual void print(std::ostream &os) const
print target value
std::string const & msg() const
std::string const & category() const
std::string m_category
category
ProgramOptions(std::string const &title="Available options")
constructor
ValueBase & operator=(ValueBase const &rhs)
assignment
ProgramOptions & add_option(ValueType const &data)
generic API to add options of various data types
virtual bool help_on() const =0
check whether help message is turned on
std::string m_title
title of options
virtual void apply_toggle()=0
apply toggle value
virtual ~Value()
destructor
a generic class for various data values
virtual bool valid_default() const =0
check whether default value is valid
ValueBase(std::string const &cat, std::string const &m)
constructor
Value & operator=(Value const &rhs)
assignment
virtual Value & toggle_value(value_type const &v)
set toggle value
unsigned char m_required
whether the value is a required option
ProgramOptionsException(ProgramOptionsException const &rhs)
copy constructor
namespace for Limbo
Definition: GraphUtility.h:22
bool count(std::string const &cat) const
virtual Value & toggle(bool t)
set toggle flag
virtual bool parse(const char *)=0
parse command
virtual void print_default(std::ostream &os) const
print default value
value_type * m_default_value
default value
virtual unsigned count_default_chars() const =0
count the length of default value string
void copy(Value const &rhs)
copy another object
std::string m_msg
helper message
virtual bool help_on() const
check whether help message is turned on
virtual Value & required(bool r)
set required flag
void print_space(std::ostream &os, unsigned num) const
print a specific number of spaces
virtual Value & help(bool h)
set help flag
top API to parse program options
unsigned char m_help
whether is help option
Check string is integer, floating point, number... Convert string to upper/lower cases.
void print_category(std::ostream &os) const
print category
metafunction for assign a source data type to a target data type
virtual void apply_toggle()
apply toggle value
void print() const
print help message
virtual void print_default(std::ostream &os) const =0
print default value
void print_msg(std::ostream &os) const
print message
value_type * m_toggle_value
only valid when this option is a toggle value
bool parse(int argc, char **argv)
read command line options
an exception class for limbo::programoptions::ProgramOptions
virtual void print(std::ostream &os) const =0
print target value
virtual bool valid_toggle() const
check whether toggle value is valid
metafunction for boolean operation
#define assert_msg(condition, message)
assertion with message
Definition: AssertMsg.h:34
virtual Value & default_value(value_type const &v, std::string const &d="")
set default value
virtual void apply_default()=0
apply default value
virtual unsigned count_default_chars() const
count the length of default value string
virtual void apply_default()
apply default value
value_type * m_target
NULL for help.