Limbo 3.5.4
Loading...
Searching...
No Matches
ProgramOptions.h
Go to the documentation of this file.
1
10
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
25namespace limbo
26{
28namespace programoptions
29{
30
35class ProgramOptionsException : public std::exception
36{
37 public:
39 typedef std::exception base_type;
44 ProgramOptionsException(std::string const& msg) : base_type(), m_msg(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
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 {}
83
87 ValueBase(ValueBase const& rhs) {copy(rhs);}
94 {
95 if (this != &rhs)
96 copy(rhs);
97 return *this;
98 }
99
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 {
196 m_msg = rhs.m_msg;
197 m_help = rhs.m_help;
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
216template <typename T>
217class 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)
237 {}
238
242 Value(Value const& rhs)
243 : base_type(rhs)
244 {
245 copy(rhs);
246 }
247
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 }
261
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 }
288
292 virtual void print(std::ostream& os) const
293 {
294 if (m_target)
296 }
297
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 }
310
318
321 virtual void apply_toggle()
322 {
324 {
326 m_valid = true;
327 }
328 }
329
333 virtual bool valid_target() const
334 {
335 return (m_target != NULL);
336 }
337
341 virtual bool valid_default() const
342 {
343 return (m_default_value != NULL);
344 }
345
349 virtual bool valid_toggle() const
350 {
351 return (m_toggle_value != NULL);
352 }
353
357 virtual unsigned count_default_chars() const
358 {
359 std::ostringstream oss;
360 print_default(oss);
361 return oss.str().size();
362 }
363
367 virtual bool help_on() const
368 {
369 // only true when this option is already set
371 return true;
372 else return false;
373 }
374
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);
386 return *this;
387 }
388
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 }
400
405 virtual Value& help(bool h)
406 {
407 m_help = h;
408 return *this;
409 }
410
415 virtual Value& required(bool r)
416 {
417 m_required = r;
418 return *this;
419 }
420
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
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");
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 limboAssertMsg(num < 1000, "num out of bounds: %u", 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
532inline ProgramOptions::ProgramOptions(std::string const& title)
533 : m_title(title)
534{}
535
536template <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
assertion with message
#define limboAssertMsg(condition, args...)
custom assertion with message
Definition AssertMsg.h:24
helper function objects for various data types
Check string is integer, floating point, number... Convert string to upper/lower cases.
virtual const char * what() const
access message
std::string m_msg
message of the exception
ProgramOptionsException(std::string const &msg)
constructor
ProgramOptionsException(ProgramOptionsException const &rhs)
copy constructor
ProgramOptions(ProgramOptions const &rhs)
copy constructor
void print_space(std::ostream &os, unsigned num) const
print a specific number of spaces
bool parse(int argc, char **argv)
read command line options
void print(std::ostream &os) const
print help message
bool count(std::string const &cat) const
void print() const
print help message
std::map< std::string, unsigned > cat2index_map_type
mapping from category to index
std::map< std::string, unsigned > m_mCat2Index
saving mapping for flag to option
ProgramOptions(std::string const &title="Available options")
constructor
std::string m_title
title of options
std::vector< ValueBase * > m_vData
saving options
friend std::ostream & operator<<(std::ostream &os, ProgramOptions const &rhs)
print help message by override operator<<
ProgramOptions & add_option(ValueType const &data)
generic API to add options of various data types
unsigned char m_required
whether the value is a required option
virtual bool valid_toggle() const =0
check whether toggle value is valid
virtual bool help_on() const =0
check whether help message is turned on
virtual void apply_default()=0
apply default value
std::string const & msg() const
ValueBase(std::string const &cat, std::string const &m)
constructor
virtual void print_default(std::ostream &os) const =0
print default value
unsigned char m_help
whether is help option
ValueBase(ValueBase const &rhs)
copy constructor
ValueBase & operator=(ValueBase const &rhs)
assignment
std::string m_msg
helper message
std::string const & category() const
void copy(ValueBase const &rhs)
copy another object
void print_category(std::ostream &os) const
print category
virtual void print(std::ostream &os) const =0
print target value
virtual bool valid_target() const =0
check whether target value is valid
unsigned char m_toggle
true if this option is a toggle value
void print_msg(std::ostream &os) const
print message
virtual bool valid_default() const =0
check whether default value is valid
virtual bool parse(const char *)=0
parse command
virtual unsigned count_default_chars() const =0
count the length of default value string
unsigned char m_valid
true if target is set, not default
virtual void apply_toggle()=0
apply toggle value
virtual Value & default_value(value_type const &v, std::string const &d="")
set default value
virtual void apply_toggle()
apply toggle value
virtual Value & toggle_value(value_type const &v)
set toggle value
value_type * m_default_value
default value
Value(std::string const &cat, value_type *target, std::string const &m)
constructor
virtual Value & required(bool r)
set required flag
virtual Value & toggle(bool t)
set toggle flag
Value(Value const &rhs)
copy constructor
virtual bool valid_target() const
check whether target value is valid
virtual bool help_on() const
check whether help message is turned on
Value & operator=(Value const &rhs)
assignment
virtual bool valid_toggle() const
check whether toggle value is valid
virtual unsigned count_default_chars() const
count the length of default value string
virtual void print_default(std::ostream &os) const
print default value
virtual void apply_default()
apply default value
value_type * m_target
NULL for help.
virtual bool valid_default() const
check whether default value is valid
void copy(Value const &rhs)
copy another object
virtual bool parse(const char *v)
parse data from string
virtual Value & help(bool h)
set help flag
virtual void print(std::ostream &os) const
print target value
std::string m_default_display
display default value
value_type * m_toggle_value
only valid when this option is a toggle value
namespace for Limbo.ProgramOptions
namespace for Limbo
metafunction for assign a source data type to a target data type
metafunction for boolean operation
metafunction for parsing a char-based string to a target data type
metafunction for printing a target data type